Basic Texture Mapping // OpenGL Tutorial #16

Поделиться
HTML-код
  • Опубликовано: 14 окт 2024

Комментарии • 74

  • @Hansly_rz
    @Hansly_rz 11 месяцев назад +7

    my college professor gave us this assignment with barely any opengl explanation. He threw around methods like glbindbuffer and other methods around left for us to research. I am so happy this video exists. Thank you so much!

    • @OGLDEV
      @OGLDEV  11 месяцев назад

      Glad it helped!

  • @dimension-ji7xk
    @dimension-ji7xk 3 года назад +5

    Yes, this was what i was waiting for.

    • @OGLDEV
      @OGLDEV  3 года назад

      It's great to hear that :-)

  • @coderedart
    @coderedart 3 года назад +5

    I loved that slide which listed all the steps of rendering a texture. the whole process exists in multiple domains like the image file/ getting pixels is in user code/stb, the texture object and uploading pixels to it, binding it to a texture image unit in gl code, and finally sampler in a glsl.
    otoh, it also feels way more complicated than it needs to be. i don't see the point of texture unit or sampler variable (which is a signed int, if we wanted to select different unit) rather than just use the texture id that you get from genTexture.

    • @OGLDEV
      @OGLDEV  3 года назад +2

      Thank you. This design enables separation of shader and application code. Often, it is the result of HW engineers and GPU architects adapting the API to work the way their HW works. They actually have texture units in the physical HW so they may want to represent that in the API.

  • @huiminliu8699
    @huiminliu8699 Год назад

    Like it! this tutorial is very clear and easy to understand.

  • @hunterize1516
    @hunterize1516 3 года назад +2

    like it always, very detailed :)

    • @OGLDEV
      @OGLDEV  3 года назад

      Thank you :-)

  • @kspan-xj4gs
    @kspan-xj4gs 9 месяцев назад

    I was able to load a 24bit bitmap in OpenGL using only GLUT and C coding. I didn't use any special libraries other than "stdlib.h" & "stdio.h". The code was a very short and simple process. fopen() to fread the file and fclose, then proceed on as normal glEnable(), etc.
    BMP texture loaded and created a nice perfect fitting texture even with a size of 400x400, gave nice detailed look.

    • @kspan-xj4gs
      @kspan-xj4gs 9 месяцев назад

      The cool part about it was that I did it on my RaspberryPi4, running Debian Bullseye on Linux platform.

    • @OGLDEV
      @OGLDEV  9 месяцев назад

      Nice. BMP is easy to use because it is just a header followed by data which allows you to do what you described. For compressed formats you would probably prefer using a library.

  • @Byynx
    @Byynx 11 месяцев назад

    Very good this video.

    • @OGLDEV
      @OGLDEV  11 месяцев назад

      Thanks!

  • @Byynx
    @Byynx 11 месяцев назад

    At 10:24 you say the glBindTexture() upon the creation of a texture object it only binds to a target. I know we're saying what type of texture 2D or 3D is, but what is this target? And why if we use the same function after glActivateTexture() we are binding it to a texture unit or it seems to act different ?

    • @OGLDEV
      @OGLDEV  11 месяцев назад +1

      There are different types of textures - 1D, 2D, 3D, etc. The 'target' is simply the name of the type. When you call glGenTextures you create a texture handle but the system still doesn't know which type of texture this is going to be. Only when you bind it to a target for the first time the type is set and cannot be changed later. In the background of this there is also an active texture unit. The texture units allow you to access multiple textures in the shader at the same time. When you call glBindTexture you actually bind it to the requested target in the active texture unit which by default is texture0. When you create all your textures at initialization time you don't really care about the active texture unit but it is still texture0. You simply initialize them one by one on the same implicit active texture unit and during runtime you connect them to the shader by activating each texture unit and binding the texture to the correct target. Only a single target will actually work for each texture unit so be careful not to bind two textures to two different targets on the same unit!

  • @burzummmmm
    @burzummmmm Год назад

    Very good video, though I am trying to understand how the interpolated coordinates are mapped to texels; I would like a detailed video explaining

    • @OGLDEV
      @OGLDEV  Год назад

      Thanks! Since the actual mapping to texels is done entirely in HW and is beyond the control of the developer I'm not sure I will do in the near future. This is something that should go to a series on SW rasterization which I'm interested in but I don't have time for right now. I can tell you in a nutshell that the texture coordinates on the vertices are not changed after being set by the modeller (unless you're doing some fancy effect on them). Depending on how the triangle ends up on the screen the number of pixels inside it and their relation to vertices will determine their texture coordinates (this is the result of interpolation). The actual sampling will be done by simply translating the normalized coordinates to the actual texture pixels based on the size of the texture (e.g 0.5 will go to the center, etc).

  • @AlbertRyanstein
    @AlbertRyanstein Год назад

    Hey I cant find the tut_18assimp. I want to see your texture load function since I load my textures in the constructor so I don't really have a load function.

    • @AlbertRyanstein
      @AlbertRyanstein Год назад

      Sorry I have two windows open, ruclips.net/video/sP_kiODC25Q/видео.html for this tutorial ha

    • @OGLDEV
      @OGLDEV  Год назад

      The assimp tutorial is here: github.com/emeiri/ogldev/tree/master/tutorial18_youtube

  • @Byynx
    @Byynx 8 месяцев назад

    Hi, i'm trying to cast a float attribute (tex_ID) to an int in the frag shader to use it as index to texture 2 different meshes, but if i do "int index = int(v_texID);" it doesn't work properly, only if i do "int index = int(round(v_texID));" than it works fine. Do you have an idea why this is happening, why can't i just do "int index = int(v_texID);" ? The float on v_tex_ID is either 0.0f or 1.0f.

    • @OGLDEV
      @OGLDEV  8 месяцев назад +1

      There may be a numerical issue with the standard C style casting which by default rounds down the floating point and you always get zero. This is a bit odd because 1.0 is well represented in floating point. This is indicated by the fact that rounding solves the problem. Try to define 'index' as highp (highp int index) and see if that works.

    • @Byynx
      @Byynx 8 месяцев назад

      ​@@OGLDEV Already tried that with highp and it's the same, i forgot to say that i'm using a std::vector to add the vertex data, but if i use a normal float array, in that case i now can do int index = int(v_texID). It's strange.

    • @OGLDEV
      @OGLDEV  8 месяцев назад +1

      It is strange, because the vector should not affect the data. Need to investigate if there's an in-memory difference between the array and the vector.

  • @kumu2024
    @kumu2024 10 месяцев назад +1

    All talks about statically create texture coordinate, but no one (I couldn't find after many googling) explain how to calculate the texture coordinate for a 3d model.
    Don't know if it is difficult or what? why not from begining make it function-based not writing down the texture coordinates (hard-coded) like here?
    Look at Hazel game engine. it is the same and many other tutorials .
    Still I am struggling to find that text or video tutorials. Thanks anyway for the video

    • @OGLDEV
      @OGLDEV  10 месяцев назад

      I think you are referring to UV mapping which is a (mostly manual I think) process in the modelling software where the 3D model is sliced, unwrapped and then mapped to a large texture which contains all the bits and pieces that are used to texture it. For example, such texture may include all the clothes and armor of a fighter from head to toe as well as stuff like swords, skin, hair, etc. This is definitely not something which you can deal with in the rendering API. If this is what you mean then this is job belongs to the art department and the progammer simply receives the final coordinates and the texture and needs to make sure to use them correctly.

    • @kumu2024
      @kumu2024 10 месяцев назад

      @@OGLDEV
      Thanks, What I am actually trying to do is to have something like Wing3D, FreeCAD like or 123D Design that can manipulate mesh objects.
      And I want to have the ability to put texture on object, 3D objects.
      I am not sure if that is correct, I take the normals of the vertices I have and use it as texture coordinate.
      I am struggling in doing so for many days now.
      You can look at my code. At the moment, I can see some texture on the 3D objects, but they are not correct, and not shown on all faces.
      OpenGL is hard.
      Please look at my project, and choose devbranch as other branches contain other research that most of them frozen. Master/main is not updated to the development phase as I need to have stable working base before pushing them to the main branch. At the end, I want to make the project as a part of my Direct Modeling Workbench (Design456) for FreeCAD.
      github.com/MariwanJ/Design456App

    • @OGLDEV
      @OGLDEV  10 месяцев назад

      Where exactly is the code that you want me to look at?

    • @kumu2024
      @kumu2024 10 месяцев назад

      @@OGLDEV
      In this file I have a function that calculate the texture-coordinates.
      github.com/MariwanJ/Design456App/blob/main/frtk/src/halfEdge/fr_new_mesh.cpp
      that file should load mesh and create half-edge. But I am asking just for the texture coordinates how to calculate.
      void Shape::calcualteTextCoor(int width, int height)

    • @OGLDEV
      @OGLDEV  10 месяцев назад

      I'm afraid I still don't understand what you are trying to accomplish. Do you wish to apply any rectangular texture on a complex 3D model ad-hoc? When you have a model of a box you can set the tex coords of each face to go from 0,0 to 1,1 and then the entire texture will cover that face. But when the model is complex how do you expect the system to know how to match the texture to each triangle? I'm not familiar with the tools that you mentioned so I guess I'm not aware of their features when it comes to textures. I see that calcualteTextCoor makes sure the normals are calculated and then simply copies the normal XY to UV. If we have a flat grid of many triangles then all of them have the same normal. So should they have the same tex coord?

  • @AlbertRyanstein
    @AlbertRyanstein Год назад

    If I make a game and assign some textures to texture unit 25. And the people playing the game dont have 25 units, what happens? Will it not work and so I need to account for this? Or will openGL fix it dynamically

    • @OGLDEV
      @OGLDEV  Год назад

      OpenGL cannot fix such problems on its own. Whenever your game uses an optional feature or goes beyond the available amount of some OpenGL resource it simply loses some functionality (texture is not sampled, etc).

    • @AlbertRyanstein
      @AlbertRyanstein Год назад

      thank you fo reply.@@OGLDEV

  • @حسنيمحمدحسن-ت7ح
    @حسنيمحمدحسن-ت7ح 2 года назад

    If we have cube with 4 vertex texture and 8 vertices and i know uvmap how i can texture this cube?

    • @OGLDEV
      @OGLDEV  2 года назад

      I don't think you can do this with just 8 vertices because each vertex has a single texture coordinate and it is shared by 3 faces. So once you set one face correctly with tex coords [0,0], [1,0], [0,1], [1,1] and you go to the second and third face you will end up with the same tex coord appearing twice on the same face. So you have to duplicate the vertices and set the correct tex coords for each vertex according to the face.

  • @lawrencekeener25
    @lawrencekeener25 3 года назад

    how come the texture on two faces of the cube are diagonal?

    • @OGLDEV
      @OGLDEV  3 года назад

      I just threw in the texture coordinates, four corners on the first four vertices and then again on the last four vertices. So on some faces it matches and on some it doesn't. I was a bit stressed on time so I didn't want to start looking around for a perfect cube model or reorganize the vertices so that all faces will match. Sorry...

    • @lawrencekeener25
      @lawrencekeener25 3 года назад

      @@OGLDEV OH, I wasn't complaining, just curious. These are really great videos. Thank you for the response...I will look into how to apply it for the sides.

    • @OGLDEV
      @OGLDEV  3 года назад

      Sure. Each vertex is shared by three faces so it can be part of 3 to 6 triangles. You need to find some way of assigning texture coordinates to each vertex in a way that it will match perfectly to each of these triangles. I'm not sure but you may need to duplicate some vertices.

  • @abnereliberganzahernandez6337
    @abnereliberganzahernandez6337 7 месяцев назад

    jim blinn also made texture mapping

    • @OGLDEV
      @OGLDEV  7 месяцев назад +1

      That guy is definitely one of the founding fathers of 3D graphics. You can't throw a rock in that field without hitting something that he was involved in.

  • @hamedhosseinabadi5390
    @hamedhosseinabadi5390 2 года назад

    thanks

    • @OGLDEV
      @OGLDEV  2 года назад

      You're welcome

  • @0darkwings0
    @0darkwings0 2 года назад

    Hello, thank you for the tutorial :)
    I am using freeglut (I can use other libraries), what is the alternative for glactivetexture() in freeglut? (I can't find it)

    • @OGLDEV
      @OGLDEV  2 года назад +1

      You're welcome! glActiveTexture is an OpenGL call so you can use it regardless of the windowing library.

    • @0darkwings0
      @0darkwings0 2 года назад

      @@OGLDEV when I am trying to use it it not recognize it.

    • @OGLDEV
      @OGLDEV  2 года назад

      @@0darkwings0 Can you please share a log or error msg?

    • @0darkwings0
      @0darkwings0 2 года назад

      @@OGLDEV The erorr is: identifier "glActiveTexture" is undefined.
      it's recognizing every other gl functions

    • @OGLDEV
      @OGLDEV  2 года назад

      Looks like a linker error. Are you using glew or glad? And what is the operating system?

  • @kyvexium
    @kyvexium 2 года назад

    I do not really understand how to set texture coordinates for a 3D model. I understand what they mean and i know how to use them in 2D.

    • @OGLDEV
      @OGLDEV  2 года назад

      You mean how to set their value? In most introductory texts you set them manually on something like a cube so you use the corners of the texture ([0,0],[0,1],...) but in practice with a real world model the modeling artist will fit the texture to the model using a process called UV unwrapping and the SW will calculate the texture coordinates per vertex. So your job is mostly to load the coordinates into the vertex buffers, load the textures with the correct parameters and access the texture in the fragment shader.

    • @kyvexium
      @kyvexium 2 года назад

      ​@@OGLDEV Yeah for example i have a cube and i have an image with a cat. I want each face of the cube to have the image of the cat. How do i do that?

    • @kyvexium
      @kyvexium 2 года назад

      I want to see how is the texture placed and how it is repeated on the cube

    • @kyvexium
      @kyvexium 2 года назад

      ​@@OGLDEV After some time playing with the x,y coordinates, i found out that i could start from the first vertex and then second and then third and so on until 8th vertex and put the texture coordinates for the vertices relative to the face that the camera was looking

    • @OGLDEV
      @OGLDEV  2 года назад

      Yes, what you are doing is exactly this manual setting of the texture coordinates that I was referring to. But you are probably not getting the cat correctly on all the six cube faces. This is because each vertex is shared between three faces so you end up with a face where you can't place the four texture coordinates correctly. The solution is simply to duplicate the vertex (same position) and use different texture coordinates for each face. Each face will be constructed from the specific vertices assigned to it.

  • @АркадийСаакян-ч5н
    @АркадийСаакян-ч5н 2 года назад

    Are you russian? you speak with an accent

  • @ProgrammingWithRook
    @ProgrammingWithRook 10 месяцев назад +1

    OGLDEV-GPT

    • @ProgrammingWithRook
      @ProgrammingWithRook 10 месяцев назад

      I've spent 3 days, playing with many numbers and i got to texturing 6 sides, 4 perfect 2 half rendered, i've lost them nunmbers as i have played with it so much... I will watch this again and again and again if i have too

    • @OGLDEV
      @OGLDEV  10 месяцев назад

      @@ProgrammingWithRook Good luck :-)