Jump to content

Kamjam66xx

Member
  • Posts

    117
  • Joined

  • Last visited

Reputation Activity

  1. Informative
    Kamjam66xx reacted to Unimportant in RenderEngine   
    Did a quick review, and there's some problems. Some minor and some very serious.
    Some of your classes that try to manage resources actually don't. Look up the rule of 3/5/0. Here's an example from Skybox: //Skybox.h private: Mesh *skyMesh; Shader *skyShader; //Skybox.cpp SkyBox::SkyBox(std::vector<std::string> faceLocations) { // shader skyShader = new Shader(); You've got some raw member pointers for which you then allocate memory with new. What happens when a Skybox instance gets copied? The default copy constructor will simply copy those raw pointers so now you've got 2 skyboxes pointing to the same resources. When one does some modifications to those resources, the results will be reflected to both, leading to weird bugs. Furthermore, when one skybox is destroyed and frees it's memory (you've commented out the deletes in the destructor for some reason? - now you're leaking memory) the other skybox is pointing to deleted resources. The rule of 3 (pre C++11) used to say that if your class manages resources like this you must write:
    Copy constructor and assignment operators that perform a deep copy. That is, allocate their own memory and copy the contents over so now both instances have their own resources.
    A destructor that frees the resources.
     
    This then later became the rule of 5 in C++11 as move semantics where added. If applicable you should now also add a move constructor and assignment operator that can steal the source's resources cheaply.
    The rule of 0, which I subscribe to, states that classes that manage resources, and thus have custom copy/move constructors/assignment should deal exclusively with the ownership and management of their resource. Other classes can then use these RAII objects as members so they themselves don't need to worry about any of it and need 0 custom copy/move operators.
     
    So, in short, you should probably wrap the management of skyMesh and skyShader into another class that's solely responsible for managing it.
     
    One could argue that there only ever needs to be a single Skybox and it won't be copied. In that case you should delete the copy constructor and assignment operator to prevent accidental copies. Even then you should wrap those pointers into a std::unique_ptr that manages their lifetime for you so you can't leak. You should not be using naked new and delete.
     
    You make similar resource management errors throughout your code, here's another example:
    //Texture.h private: //<snip> const char* fileLocation; //Texture.cpp Texture::Texture(const char* fileLoc) { //<snip> fileLocation = fileLoc; //<snip> } bool Texture::LoadTextureA() { // loads image. one and done. unsigned char *texData = stbi_load(fileLocation, &width, &height, &bitDepth, 0); You give a C style string with the file location to the constructor of this class which it then stores. A C style string is nothing but a char pointer pointing to the actual string which lives somewhere outside the Texture class. Then, possibly at a much later time, you use this pointer in your member functions. What if the string is already gone by then and the pointer is dangling ? For small aggregations like this it makes no sense to have the caller worry about the string lifetime. Simply make fileLocation a std::string so each Texture has it's own file location stored safely inside, not depending on the outside world. 
    There's lots more places in your code where you use C style strings. You should convert them all to std::string to minimize the chance of similar bugs. If you need a C style char pointer to pass to the GL functions use std::string::c_str to get a C style string pointer from a std::string at the very last moment.
    signed/unsigned interrelations. for example:
    for (size_t i = 0; i < (MAX_POINT_LIGHTS + MAX_SPOT_LIGHTS); i++) MAX_POINT_LIGHTS and MAX_SPOT_LIGHTS are signed int, so the result of adding them is also signed int, which is then compared to a size_t which is unsigned. Your compiler should emit a warning for this. Signed and unsigned interrelating can lead to different results then what you were expecting. <more info>. It's probably not a problem here because the numbers are so small but it is a general code smell you should watch out for. My way of doing things is to always use signed, for everything (math related, bit manipulation is something different), even things that can't be negative. It's much better to catch some value that can't be negative being negative in the debugger then see it as some huge overflown positive value that might escape detection. If you really need the extra bit, use a larger datatype. size_t is a abomination that should never have been unsigned. (altough understandable, it's a carry-over from C from decades ago when that extra bit really was required). When you get a size_t from some function call, convert it to signed asap. I've my custom made template function that assigns the value of a size_t to a given signed variable and throws when it won't fit. In this case you can offcourse just change to "int i = 0".
    There's probably more things to find but I guess this is enough to get you busy refactoring for a while.
  2. Informative
    Kamjam66xx reacted to straight_stewie in Shaders - Calculating Shadows   
    Well, that depends. There are three types of branching, atleast in terms of what the compiler can see:
     
    Static branching: Everything is known at compile time and is optimized away. There is no actual branching occuring when your shader runs. Statically Uniform Branching: The compiler can't easily know for sure what branch is taken, but it does notice that it is based only off of constants/uniforms. Therefore, the compiler can know that the decision taken will be the same for every instance of the shader, and therefore each instance of the shader will be in the same place at the same time. Coherency is maintained (really, really good for GPUs.). Dynamic branching: Nothing can be determined at compile time. The shader may or may not be in different places for different instances. The one that you should probably still care about is dynamic branching, however, newer hardware doesn't have as much a problem with it as older hardware does.
     
    The first question one should ask: What does the image look like if you don't do any branching? If the image is the same, is performance better, or worse?
     
    If the answer to that is "unnaceptable", then one might consider: Is there some non piecewise function that approximates the piecewise function I have? This is a very hard question to answer, and these types of questions are a big part of the reason that people always say that computer graphics is a very hard field.
  3. Like
    Kamjam66xx reacted to Franck in Shaders - Calculating Shadows   
    I don't understand, that if is necessary that's the dot between the normal and direction. if it's 0 it mean your angle is 90 DEG or more which mean you don't show the specular as it's not toward you view. Unless i misread your variables.
  4. Like
    Kamjam66xx reacted to WolfLoverPro in Where Can I Learn To Program For Free!? What is best lang too?   
    lmfao i went with i just want money and it took me to java..................... maybe its bad but let me be honest.. i kind of do want it for the money lmfao but ive always been interested in computer jobs so idk
  5. Informative
    Kamjam66xx reacted to factorialandha in Where Can I Learn To Program For Free!? What is best lang too?   
    First i would pick a language that you want to learn based on what you want to do -> the info graphic below is quite fun (just as a tid bit)
     
    As for resources, im not aware of any free ones, but Udemy has quite a lot of discount deals regularly so might be good to look at.
     

  6. Like
    Kamjam66xx reacted to trag1c in Multi-Threading C++ & OpenGL   
    Profiling is a measurement of performance. This can be as simple as measuring frame time (the inverse of fps which is a metric that's far more valuable then fps) or as low level as measuring function execution time and the number of calls to funcations. 
     
    I highly suggest looking into Profiling before you try any optimizations because it tell you where you need to improve performance.
     
    Theres also the 80-20 rules (or any derivatives such as 90-10) which means you will get 80% performance increase for optimizing 20% of your code. So Profiling helps you find that magical 20%.
  7. Like
    Kamjam66xx reacted to nicebyte in Multi-Threading C++ & OpenGL   
    >  I guess ill save any serious attempts at multi-threading for Vulkan then, is that the conclusion i should be leaving with?
     
    Yeah I would recommend that. Focus on the fundamentals and try not to get too bogged down in the api details yet.
  8. Like
    Kamjam66xx reacted to Mira Yurizaki in Multi-Threading C++ & OpenGL   
    This tells me more that DX11/OGL is more like... proving your thing works. DX12/Vulkan is more like, you proven your thing works, but now you want to make it work better and you're positive you've tried everything else.
  9. Like
    Kamjam66xx reacted to nicebyte in Multi-Threading C++ & OpenGL   
    to drive the point home, the opengl backend of my homegrown gfx lib  is ~2000 lines of code 
    Is the vulkan one is about the same size now, but it's nowhere near being feature complete AND i've "outsourced" gpu memory management to AMD's VMA library (which could easily add anothe 1K lines if i did it myself).
    I definitely don't want to discourage anyone from learningVulkan, but those who are considering need to understand that graphics APIs are not about graphics, they are about abstracting the GPU. Learning DX12 or Vk will take a nontrivial amount of time during which you will not be dealing with actual "graphics", i.e. making pretty images. Instead, you'll be figuring out how to be efficient at feeding data into a massively parallel computer attached to your regular computer  this can be interesting in and of itself, but make sure you understand what you're getting into!
  10. Like
    Kamjam66xx reacted to Mira Yurizaki in Multi-Threading C++ & OpenGL   
    I want to +1 to this. From what I've read on developer circles, DX12 is really "DX11 Expert Mode." I can't imagine Vulkan being any different.
     
    Multithreading is something that shouldn't be taken lightly. While the concept is deceptively simple looking, executing it well in practice is horribly difficult. You have to understand your design and your code well in order to make sure multithreading is working as intended.
  11. Informative
    Kamjam66xx reacted to nicebyte in Multi-Threading C++ & OpenGL   
    That just sounds that you're calling OpenGL on a thread with no active OpenGL context. 
     
    However, in general, it is barely possible to get an appreciable speedup from an OpenGL renderer by using multithreading. Don't hope that you can, for example, call the shadow map rendering commands on one thread and scene rendering commands on the other - that will not work: the opengl driver will just synchronize those threads and everything will effectively become serialized, losing any benefit you may have had from parallelism. This isn't a question of driver quality, it's a fundamental constraint caused by the design of OpenGL. So, you're better off calling OpenGL on just one thread.
     
    One exception to this is loading textures/meshes etc from disk. Since most time is spent waiting on file reads it makes sense to split resource loading/texture and buffer creation into a separate thread(s) - create a shared context on the resource loading thread, load your textures/models on it while you do other stuff. This could improve your loading times. 
     
    If you are interested in building a multithreaded renderer, the best path forward is with new APIs - DX12 or Vulkan. They allow to split the driver overhead of recording command buffers onto multiple different threads, thus making better use of you cpu's many cores. This comes at a price of needing to handle GPU-side synchronization and memory management yourself though - it is a very daunting task and I don't think someone who is beginning graphics should bother with it. I promise you it's way more fun to play with lights and materials than to look for synchronization bugs in your vulkan code
     
  12. Like
    Kamjam66xx reacted to trag1c in Multi-Threading C++ & OpenGL   
    Unsure with ogl but dx you would create a command list with a deferred contex in each thread and then submit them to the immediate list to rendered. Should essentially be the same as dx.
     
    However i guarantee that you can drastically improve performance with far less complexity added to the program. Have you even profiled your application yet?
  13. Informative
    Kamjam66xx reacted to Unimportant in Multi-Threading C++ & OpenGL   
    Use threads to divvy up the workload and compose the data that should be sent to OpenGL but only have a single thread (the one that opened the OpenGL context) handle the calls to OpenGL. Also consider that the error might be in your code, not necessarily anything to do with OpenGL, are you sure you don't have any data races? atomicity issues ? OOE problems that break naive mutex attempts?, etc...
  14. Informative
    Kamjam66xx reacted to KarathKasun in Multi-Threading C++ & OpenGL   
    Im not familiar with C++ terminology or variable naming conventions to be honest.  But in general you would have an input thread write to something like a global variable, and the rendering thread read that global variable to determine how to update the output.
     
    You still need a way to sync the threads or deal with any unused input data when the render thread slows down though.
     
    http://discourse.glfw.org/t/multithreading-glfw/573/2
    Some good info there.
     
    I actually had this problem in python while writing a extremely fast threaded implementation of the basic turtle vector library.  It is a major PITA to work around.
  15. Like
    Kamjam66xx reacted to KarathKasun in Multi-Threading C++ & OpenGL   
    AFAIK OGL is not thread friendly.  With how threading works, you would do polling in a thread to fill a buffer and have the GL thread collect inputs from that buffer.  Not sure this would be any better than doing the polling in the GL thread though.
  16. Informative
    Kamjam66xx reacted to nicebyte in GLSL error highlighting HELP ME!   
    OpenGL ES is just a version of OpenGL for mobile devices. I would not say that it is simpler. Later versions of OpenGL ES (3.1+) supported by more powerful devices like adreno 630 are getting close in terms of capabilities to the desktop counterpart (i.e. 3.2 has compute shaders). Earlier versions (GL ES 2.0) have a  smaller API surface, however they have limited capabilities, making it harder to do certain things (and effectively sometimes forcing you to have two different paths if you want to support older hardware). GL ES 2 market share has been shrinking though. 
  17. Informative
    Kamjam66xx reacted to nicebyte in GLSL error highlighting HELP ME!   
    If you do decide to go the CMake route, look into the `add_custom_command` directive. You can get glslangValidator binaries from the Khronos website (https://www.khronos.org/opengles/sdk/tools/Reference-Compiler/) or just compile it from source (https://github.com/KhronosGroup/glslang).
     
    I could post a snippet from my own cmake file here however, it won't work for you because my setup is most likely different from yours. If you try it and get stuck, just post here, maybe i'll be able to help.
  18. Informative
    Kamjam66xx reacted to nicebyte in GLSL error highlighting HELP ME!   
    If you're using visual studio and cmake, it's possible to pre-validate your shaders with glslangValidator as part of the build (that's what I do). It reports shader compile errors within the IDE (not in realtime though, only when you build) before the application has the chance to run and show you a black screen ?
     
    In a pinch, you could try using http://shader-playground.timjones.io (just make sure to pick GLSL as the source language). 
    It has the added advantage of showing you the generated SPIR-V or DXIL (in case you want to explore that), and ability to chain different tools together (like putting generated SPIR-V through SPIRV-Cross).
  19. Informative
    Kamjam66xx reacted to reniat in Cmake & assimp   
    That's a really bad habit to get into. If you've never used it before, there's a good chance that the answer might be obvious after a bit of googling.

    Have you tried looking through https://github.com/assimp/assimp/blob/master/Build.md ?
  20. Informative
    Kamjam66xx reacted to Franck in GLSL error highlighting HELP ME!   
    Give a try to OpenTK. GLSL is so far the same code structure.
    There is very very small difference but i haven't noticed it until i read about them and found out i intuitively used the correct method. Not a real example but it's like if Shader was called Shaders with an "s".
     
    Anyway OpenTK does GLSL plus different versions at the same time too. They made different namespace to split them. I do believe i could do a mass replace and just change the namespace and boom it would work. Plus i love the touch of making another lib with a simple winform control, it's useful for very quick tests.
  21. Informative
    Kamjam66xx reacted to Franck in GLSL error highlighting HELP ME!   
    This extension works for my GLSL project : https://marketplace.visualstudio.com/items?itemName=DanielScherzer.GLSL
    A few things don't show up but that's like 1 out of 50 errors.
     
    But nowadays i did fall back on using OpenTK and it's 100%  supported because it's a wrapping lib.
     
  22. Like
    Kamjam66xx got a reaction from SmilesRising in Clickbait titles and thumbnails   
    Judging by how fast they get around 1,000,000 views on the last few videos, i think theyre doing fine.
  23. Funny
    Kamjam66xx got a reaction from soldier_ph in Post Linus Memes Here! << -Original thread has returned   
    These are good shots. If i was editing, id get as many people like that guy in the backdrop as possible.
  24. Like
    Kamjam66xx reacted to Nicnac in Post Linus Memes Here! << -Original thread has returned   
    Made a thumbnail, thank me later LTT
     

  25. Informative
    Kamjam66xx reacted to reniat in First portfolio programs   
    Unfortunately, being a convincing person is likely not enough if you don't have any of those certificates, depending on the size of the company. You will definitely want something to demonstrate skill, and tbh even with a solid portfolio you will have to work pretty hard to get your foot in the door. My company has a flat requirement of a 4 year degree in computer engineering or computer science, and a min gpa of 2.8 (it's not super high, but still) before you can even be considered for an interview, let alone the job. Now that has a lot to do with the fact that we get thousands and thousands of applicants and need a way to filter, but still.
     
    I don't say this to discourage you, but just to make you aware so that you're not discouraged if you get a lot of rejections when you actually start applying places. It doesn't necessarily mean you weren't skilled enough, it just means they probably just wanted a bit of safer hire.
×