Тёмный

Rendering a Quad | C Game + Engine From Scratch 02 

Dylan Falconer
Подписаться 8 тыс.
Просмотров 29 тыс.
50% 1

Learn game programming: programvideoga... (free course using Odin + Raylib!)
Programming newsletter: dylanfalconer....
X: x.com/falconerd
I had to re-upload this one because I left out an important detail - the contents of global.c. It's been spliced in at 4:09. Apologies for that, I'll be more careful when editing in the future.
Code used in recording: github.com/Fal...
Pixel art for this series is custom made by Presley Carvalho. Check out his website here: perigic.com/
Background pixel art for this series is Kings and Pigs by Pixel Frog. Check it out here: pixelfrog-asse...
Music for this series is from Breezy's Mega Quest by RyanAvx. Check it out here: ryanavx.itch.i...

Опубликовано:

 

26 сен 2024

Поделиться:

Ссылка:

Скачать:

Готовим ссылку...

Добавить в:

Мой плейлист
Посмотреть позже
Комментарии : 34   
@JoonaM_
@JoonaM_ 2 года назад
The result of this episode might not render a quad on all drivers (without shaders). My computer for example doesn't, IF the profile is set to core. The profile is defaulted to compatibility here because of the bug I mentioned in the previous video (glSetAttribute must be called after SDL_Init())
@kaiweiyeo4279
@kaiweiyeo4279 8 месяцев назад
@Takorautaselleri I've encountered the same problem on my PC. I have the vertex and fragment shaders in Episode 3 but they are window simply pops open and closes. How do I solve or debug the issue? Thank you. P.S. Does the OpenGL Version matter? 3.3 or 4.6? Core or compatibility?
@JoonaM_
@JoonaM_ 8 месяцев назад
​@@kaiweiyeo4279The OpenGL version should only determine what functions you can call. However in this very specific case it might also determine whether a triangle is drawn or not. In modern OpenGL you would never draw anything without shaders, and it's usually only done in beginner tutorials for simplicity. However it should not have anything to do with the window closing. There are a bunch of different reasons why this could be happening. A very simple debugging method is to call glGetError() and trying to pinpoint which function call generates the error (and what the error code is).
@onyx_7187
@onyx_7187 2 года назад
Hi, C programmer here, I have many questions and some critiques. 1 ) Why are you using a mix of SDL and OpenGL instead if just SDL? At least from this video it doesn't seem like you are doing fancy OpenGL specific things, so why not go full SDL? All of this episode about rendering a quad and the next one about shader would not be needed , since SDL makes it trivial to display a square and load texture files. It's also much much much more portable because all the I/O is handled by SDL itself and they have already done all the code to make it work nicely and efficiently on all systems. 2 ) It's more conventional, in C , to have a folder called srcs with subfolders etc... that only contains the .c files, and to put the .h files in their own folder, usually named includes/ , include/ or incl/ 3 ) Gobal variables is frowned upon for a very very good reason it. There's nothing dogmatic about it. You want to be able to read your code clearly and know what happens at all times. Global states defeats that purpose. You cannot, by just eyeing the code, tell which parts are reading / modifying the global state. If you want to use a global-ish variable, you can make a getter function that retrieves it for you. Now, you want to know where this variable is read? Grep the getter function. You want to see where it is modified? Grep the setter function. There's also no shame in putting things in structs and passing them around. Also, one would argue that calling your global struct "global" doesn't help readability, wouldn't it be better to name it "window" or "RenderStruct" 4 ) The Error macros are pretty cool though may also be confusing , but here's a cool macro for you # define DEBUG(msg,...) fprintf(stderr, in file %s:%d)" msg " " , __FILE__, __LINE__, ##__VA_ARGS__) , Now you can do DEBUG("Your format string here") and it will print like a normal printf, with the file name and the line the error came from :). If you were using SDL, you should use SDL_Log instead of frprintf 5 ) Pragma once is nice, I just want to touch on the "It's a lot to write". I agree with that, however VisualStudio code has a feature that lets you write "snippets" basicaly code that completes itself once you write the keyword, using it it's nice for cases like this
@DylanFalconer
@DylanFalconer 2 года назад
Hi there, happy to answer your questions: 1. Because this way people can replace SDL with their own window + context code of choice (GLFW, etc) and still benefit. This isn't an engine locked into SDL, I want to keep SDL usage as minimal as possible because then the knowledge can be more broadly applied. 2. I'd have to look into that, you are free to arrange your header files how you want. 3. You can tell which parts of the code-base are modifying the global state because they include the global header and access the global state. If you don't like the paradigm you are free to use dependency injection or something similar. Have you shipped a game without using globals? I'm interested to know because all game developers I've seen seem to end up using globals or something like a singleton in OOP languages. 4. Sure that macro is pretty cool, can you explain how the others are confusing? I think ERROR_EXIT and ERROR_RETURN are pretty straightforward. As for the SDL_Log part, I covered that above. 5. Using editor features to auto-create things like include guards is nice, I agree!
@onyx_7187
@onyx_7187 2 года назад
@@DylanFalconer 1) Okay, that makes sense. I was just wondering because it is a lot more code and effort to use openGL vs just SDL, especially for a simple game that isn't going to do anything fancy. 2 ) I know, I'm just saying this is the conventional way to do it, the way I've been doing it and the way most C programmers do it, and it how it is taught in general. 3 ) Yes and no. You can't really grep for the include statement, because you will get the entire file back. You can grep for get_global_state() and get exactly where that is used , i.e, exactly where you are using the global state. All I'm saying is, you can have "global-ish" variables, by putting that global state in a file, and making setter and getter functions. The code will be much more readable than if you just include it and use the variables in there. Also, the fact that most people end up using globals doesn't mean you should. Most programmers aren't good programmers, and good programmers should use globals only if necessary. The "use whatever method as long as it solves the problem" is how you end up with bad code, because many methods can solve a problem, but only a few will solve it well. And no, I don't know many game programmers, I certainly haven't read through their code, but I have made a small game engine in C, and I have not used globals anywhere in that code
@DylanFalconer
@DylanFalconer 2 года назад
@@onyx_7187 About point 2, is this just for libraries or for whole projects? As for the globals issue, I had a build earlier that kept each module state internally and passed back pointers from the init functions, then when you called specific functions in your game like entity_create, you'd have to pass in a reference to the struct entity_state. I haven't actually used globals before now, but I think this usage is innocuous. Your rebuttal to the dogma by being dogmatic about it is proving that part of my point, however much merit your argument may have. Thanks for the reply, I'll have a think about whether I want to try to pivot from here or continue on this course. Also I don't think that you should use "whatever" method, you should use the most straightforward one that solves the problem and is not likely to cause future complications. Do you have a link to your engine? I'd love to check it out
@onyx_7187
@onyx_7187 2 года назад
@@DylanFalconer huh, I swear I answered you here, but I guess RU-vid deleted my comment for whatever reason. I believe I said something along these lines : I'd be glad to share the engine with you via private message or other means. I did use "globalist" variables in my engine as well. The struct is static, in a file, and you can only access it via getter functions. Also the file structure is per project, but you may keep your headers and srcs in different folders at different levels, and you would usually have one makefile per srcs / includes pair
@DylanFalconer
@DylanFalconer 2 года назад
That sucks - I hate when that happens, especially when I've written a long comment. If you have Discord, there's a link to the channel server on there, otherwise you can email me at: me at falconerd dot com. Perhaps a video discussing the pros and cons of globals could be useful. I hope I didn't give people the idea that you should just stick all your state for everything into globals.
@LocalTrashyt
@LocalTrashyt Год назад
If you came into an issue where the `glDrawElement` function was crashing, try moving the `SDL_GL_SetAttribute` functions after the `SDL_Init` function
@乌云-o3e
@乌云-o3e 8 месяцев назад
For anyone using OS X this might be helpful.
@乌云-o3e
@乌云-o3e 8 месяцев назад
Actually, do you know the reason why?
@IsaacCode95
@IsaacCode95 Год назад
why not pragma once instead of ifndef ? also i got everything working but for some reason i don't get the same shape as you
@DylanFalconer
@DylanFalconer Год назад
ifndef was a habit from when I was writing portable C89 code - it didn't allow for pragma once.
@lukaszborowka
@lukaszborowka 3 месяца назад
I've had problem with visual studio build tools and kept getting an error that the stdio.h was not found. Turns out, it couldnt be found because there was no stdio.h in my version of vs. Tried with multiple versions and other "solutions" - same thing. From what I found, it's a common issue that visual studio casually doesnt install something important. Anyway, I tried compiling with MinGW and for now, there were no issues. Will update if something crashes on MinGW later on
@DylanFalconer
@DylanFalconer 2 месяца назад
Yeah, I use PortableBuildTools nowadays - makes everything simpler
@Speykious
@Speykious Год назад
Love the Rust-like number types. :D
@matej538
@matej538 5 месяцев назад
how do you have your explorer compact like that?
@sphinxturner3520
@sphinxturner3520 2 года назад
Which IDE do you use?
@DylanFalconer
@DylanFalconer 2 года назад
In this video I am using Kakoune, but in later videos I switch to Neovim.
@kotvkvante22
@kotvkvante22 2 года назад
Лучший🐱
@Goukiesm
@Goukiesm 2 года назад
Very good tutorials. Could you zoom in or increase the font size of your editor? I'm having a hard time reading your code and text in general and I'm only able to watch it on my computer.
@DylanFalconer
@DylanFalconer 2 года назад
Thanks, I have increased the size from ep 3 onwards, are they readable?
@Goukiesm
@Goukiesm 2 года назад
@@DylanFalconer They're fine on my computer now, but on my cell phone I have to get very close to the screen to read it properly. Just a little bit bigger would be great!
@DylanFalconer
@DylanFalconer 2 года назад
@@Goukiesm For me it's already huge - can only see 34 lines on my screen. But just for you I'll try a bit larger for ep 5
@chrismartin899
@chrismartin899 2 года назад
@dylan falconer, love the tutorials. Some RU-vidrs who's code and terminal is well sized are @john hammond, @ippsec and @networkchuck Essentially your text on screen only needs to be the code you're discussing. This makes it much more accessible to mobile viewers. I've not yet seen your newest videos, but I will be bringing through them
@soto1638
@soto1638 7 месяцев назад
Too bad I can't read a darned thing going on at the screen.
@ozzy0794
@ozzy0794 2 года назад
Very nice! I see no square still, but will make sure the code is right and in the next class i'll see it render =). I'm getting the warning "src\engine ender ender_init.c(32): warning C4477: 'fprintf' : format string '%s' requires an argument of type 'char *', but variadic argument 1 has type 'const char *(__cdecl *)(void)''" in the line where it says ERROR_EXIT("Could not init SDL: %s ", SDL_GetError()); but after googlin it couldn't find out how to fix it. Can i ignore this warning for now or should i look to fix?
@erfer
@erfer 2 года назад
const char *(__cdecl *)(void) looks like a function pointer, make sure there are parenthesis at the end of SDL_GetError()
@DylanFalconer
@DylanFalconer 2 года назад
I actually made a mistake in ep 2 that is covered at the start of ep 3. The ERROR_EXIT macro should have exit(1) after the fprintf
@DylanFalconer
@DylanFalconer 2 года назад
Oh that error actually doesn't have to do with that mistake. I'll look into it
@ozzy0794
@ozzy0794 2 года назад
@@DylanFalconer Hey, i actually found out the error already, just forgot to quit an exit(1) from " if (!gladLoadGLLoader((GLADloadproc)SDL_GL_GetProcAddress)) { ERROR_EXIT("Failed to load GL: %s ", SDL_GetError()); } " in render_init.c, thanks again! (also thank you very much for uploading the classes code in github, it's easier to follow and debug that way!)
@DylanFalconer
@DylanFalconer 2 года назад
@@ozzy0794 Great, I'm glad you figured it out!
Далее
Let's Program Doom - Part 1
25:13
Просмотров 432 тыс.
Make Your Own Raycaster Part 1
16:52
Просмотров 424 тыс.
Writing 2D Games in C using SDL by Thomas Lively
47:32
Просмотров 186 тыс.