Open GL and Only One Texture Loads

  1. 6 months ago

    Chris H

    10 Mar 2018 Pre-Release Testers, Xojo Pro, XDC Speakers Grand Rapids Michigan

    I'm unable to load more than one texture in OpenGL.
    Only the last one I load ever renders, all subsequent polygons with any texture just use the first texture.
    To make it more frustrating, all polygons rendered without a texture after are invisible.

    I thought it was happening when I called OpenGL.glBindTexture, but I don't believe that now. I think it's happening when I load the textures while I'm initializing the scene (OpenGL.glTexImage2d)

    Anyone have any words of wisdom?
    I know there are a lot of OpenGL gurus on this forum

    Thanks in advance.

    (Yes, providing a zipped link to the entire project would be helpful).

    I think your problem is that you are making illegal calls between glBegin and glEnd, specifically you are trying to change the bound texture. See https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glBegin.xml which lists the legal commands.

    I think the solution here would be to modify X3_RenderModel so that the glEnd call is at the end of the loop that draws the polys. In other words, after the "next j" statement rather than after the "next i" statement.

  2. Bernardo M

    is not verified 10 Mar 2018 Pre-Release Testers

    I think is the oglname, look at xojo3d tutorial .

  3. Chris H

    10 Mar 2018 Pre-Release Testers, Xojo Pro, XDC Speakers Grand Rapids Michigan

    That’s the tutorial I copied and it’s not working.
    They have a more advanced set of classes that doesn’t exhibit the same issue, but it would take forever to rework it into my project.

    I’ll dig in there more to see if I can fugure out what they changed in the loading.

  4. Bernardo M

    is not verified 10 Mar 2018 Pre-Release Testers

    I use that library and load hundres of textures, maybe the tutorial fail in some part, look at oglname (it's a number) always is different for diferrent textures.

  5. Chris H

    10 Mar 2018 Pre-Release Testers, Xojo Pro, XDC Speakers Grand Rapids Michigan

    Here is what I can now confirm:
    The OGLNames are created correctly and are distinct
    I'm referencing them correctly before rendering to the polygons.

    I can verify that the wrapped object I have in the Xojo project have distinct images via their memory block size.
    I can't really tell what is inside the OpenGL environment (black box).

    When I load the images in a loop, regardless of the name used, the 1st (and only the 1st) texture will load and nothing else will render correctly. I'm guessing all polygons after are anticipating a texture that isn't drawn on them, so they are invisible.

    Is there any function I need to call after loading a texture into OpenGL (when generating the OGLName) or after I set it so that a buffer (or something) will clear?

    I've done some searches online and found that I'm not alone with this problem, although nobody else posted a way to resolve it.... Some of those forums are just full of people being trolls.... how refreshing the Xojo community is!

  6. Brian O

    10 Mar 2018 Pre-Release Testers, Xojo Pro Calgary, AB

    Curious, but how did you go about checking the amount of memory that was available to textures?

  7. Chris H

    10 Mar 2018 Pre-Release Testers, Xojo Pro, XDC Speakers Grand Rapids Michigan

    The wrapper referenced in (tutorial online) loads the graphics into a bitmap, ready for OpenGL. So with a breakpoint I can evaluate the properties.

  8. Bernardo M

    is not verified 10 Mar 2018 Pre-Release Testers
    Edited 6 months ago

    I checked and that tutorial I do not test it, I use the X3 library, do you ask to @Alwyn B ?

  9. Tim H

    10 Mar 2018 Pre-Release Testers Portland, OR USA

    @Chris H Only the last one I load ever renders

    @Chris H When I load the images in a loop

    Make sure you're creating a new object to hold the texture every time. A common error is to reuse the object within the loop and append it to an array. The result is that all the array elements point to the same object, so they all see just the last values that were processed.

  10. David C

    12 Mar 2018 Pre-Release Testers, Xojo Pro Derby, ITM

    I had a look at the Xojo3D samples and found it gave an exception error on 64-bit Windows, especially with aggressive compiling. 32-bit Windows and macOS 64-bit was unaffected. I have no idea is this is related to your issue.

  11. Alwyn B

    12 Mar 2018 Pre-Release Testers, Xojo Pro Johannesburg, South Africa
    Edited 6 months ago

    Chris, I just thought of something else you could check. I recall that some of the older OpenGL drivers requires that your texture resolutions are in perfect squares (e.g. 32x32, 64x64, 128x128 etc), and when you load a texture with any arbitrary resolution (e.g. 120x36) it fails.

    I only has this issue with much older OpenGL drivers though. What version of windows are you using?

  12. Chris H

    12 Mar 2018 Pre-Release Testers, Xojo Pro, XDC Speakers Grand Rapids Michigan

    Tim yes, it's a different object every time.
    David, on Windows the only issue I had was with the high dpi setting on. It was strange, shrunk the rendering. I'm sure there is a flag that is needed so that it'll behave.

    Alwyn, I did note this early too. Your tutorial had a caution about that. I went back and resized my images correctly, but still no joy.
    Failing to load would be great. The impact is that it renders everything else invisibly.

    This is a real stumper. Perhaps I can build a simple example that exhibits it and post.

  13. Eugene D

    12 Mar 2018 Pre-Release Testers, Xojo Pro Canada scispec.ca
    Edited 6 months ago

    @Chris H This is a real stumper. Perhaps I can build a simple example that exhibits it and post

    This would be helpful.

    A few parts to look at might be: 1) coding of RGB values. Sometimes the values are RGB, while other times it’s BGRA. This can prevent textures from appearing. 2) there seems to be an error in the direction of Xojo windings (clockwise and counter-clockwise) in the OpenGL plugin which will draw the textures ‘away’ from your viewpoint 3) doublecheck messageblock references. I have made this mistake a few times with pointers.

    There are other possible areas where coding textures could be not drawn and an example would be helpful. I know it’s a pain to make, and it’s really helpful to those helping you. :)

    Edit: Allwyns plugin works well. The Xojo OpenGL control has these issues.

  14. Chris H

    12 Mar 2018 Pre-Release Testers, Xojo Pro, XDC Speakers Grand Rapids Michigan

    Is it possible to add a project or zip to the thread? Seems that would be easier than trying to copy the relevant bits here.
    I'm positive this will be a one line fix when it's done..... Sigh.

    again here's the scenario spelled out a little more clear (maybe it will jog something...)

    ** If anyone helps me solve this and is going to XDC there will surely be consumable rewards for the help!!! (ツ)

    Situation 1

    1. Add two polygons
    2. Render
    3. They show properly

    Situation 2

    1. add two polygons
    2. set them to the same texture (and only load one texture)
    3. all is ok

    Situation 3

    1. add two polygons
    2. load two textures
    3. Assign one texture to each polygon.
    4. The first loaded texture shows on both polygons

    Situation 4

    1. Rerun 2 or 3 (above)
    2. add another non-textured polygon
    3. It won't show at all..... If I comment out the textured polygons the non-textured will appear again.

    It's both very odd and distressing. I've lost over a day toiling with this.

    I have this in the open event of my OpenG3Surface

    X3_Initialize
    
    Dim m As new X3Core.X3Model()
    
    m.Vertex.Append new X3Core.X3Vector( -1, -1, 0 ) // 0
    m.Vertex.Append new X3Core.X3Vector( -1,1,0) // 1
    m.Vertex.Append new X3Core.X3Vector( 1, 1, 0) // 2
    
    m.Vertex.Append new X3Core.X3Vector( 1, -1, 0 ) // 3
    
    dim p as  new X3Core.X3Polygon( 0, 0, 1)
    p.VIndex.Append 0
    p.VIndex.Append 2
    p.VIndex.Append 1
    p.UVMap.Append new X3Core.X3UVCoordinate(0,1)
    p.UVMap.Append new X3Core.X3UVCoordinate(1,0)
    p.UVMap.Append new X3Core.X3UVCoordinate(0,0)
    
    dim t as new X3Core.X3Texture( imageb ) // this is the only texture that will show regardless of what texture is loaded after.
    p.Texture = t
    
    m.AppendPolygon p
    
    dim p2 as  new X3Core.X3Polygon( 0, 0, 1)
    p2.VIndex.Append 0
    p2.VIndex.Append 3
    p2.VIndex.Append 2
    p2.UVMap.Append new X3Core.X3UVCoordinate(0,1)
    p2.UVMap.Append new X3Core.X3UVCoordinate(1,1)
    p2.UVMap.Append new X3Core.X3UVCoordinate(1,0)
    
    
    dim t2 as new X3Core.X3Texture( imagea )
    p2.Texture = t2
    
    m.AppendPolygon p2
    model.Append m
    
    
    setMyPerspective
    Render

    Using the X thoughtful examples from www.xojo3d.com , the constructor of the texture wrapper is as follows.

    ' www.Xojo3D.com
    
    Dim x, y, offset As Integer
    Dim textCol As Color
    Dim textMaskCol As Color
    Dim alpha As Byte
    dim m as picture
    
    if texture.HasAlphaChannel then
      m = texture.CopyMask
    end if
    ' convert pictures to raw formats
    
    Width = texture.Width
    Height = texture.Height
    
    RGBABitmap = new MemoryBlock(Height * Width * 4) ' create a MemoryBlock for the OpenGL RGBA format
    
    ' loop through all the pixels of the picture
    
    offset = 0
    
    for y = 0 to Height - 1
      
      for x = 0 to Width - 1
        
        ' read the values of the current pixel
        
        textCol = texture.RGBSurface.Pixel(x,y) ' get the color of the current pixel
        if m <> nil then
          textMaskCol = m.RGBSurface.Pixel(x, y) ' get the mask (alpha) color of the current pixel
        end if
        
        ' calculate the OpenGL alpha values, using the mask values of the pixel
        
        alpha = 255 - (textMaskCol.Red + textMaskCol.Green + textMaskCol.Blue) / 3
        
        ' store the color and alpha values into our OpenGL texture bitmap
        
        RGBABitmap.Byte(offset) = textCol.Red
        RGBABitmap.Byte(offset + 1) = textCol.Green
        RGBABitmap.Byte(offset + 2) = textCol.Blue
        RGBABitmap.Byte(offset + 3) = alpha
        
        offset = offset + 4 ' move to the next pixel in our OpenGL texture bitmap
        
      next x
      
    next y
    
    ' load texture into OpenGL
    OGLName = X3_LoadRGBATexture(RGBABitmap, Width, Height)

    This is how the OGLName is created (many asked if this was the source of the problem)
    I did have some issues with masks due to the old way vs new way Xojo implements, but the sample I have doesn't use any masks.

    Public Function X3_LoadRGBATexture(RGBABitmap As MemoryBlock, width As Integer, height As Integer) as Integer
      ' www.Xojo3D.com
      
      // IMPORTANT: Image dimensions must be in power of 2 (e.g. 8x8, 16x16, 32x32, 64x64, ...)
      
      Dim idMB As MemoryBlock
      Dim oglName As Integer
      
      ' ask OpenGL for an ID that we can use for our texture
      
      idMB = new MemoryBlock(4) ' create a memory block into which OpenGL will store the ID value
      OpenGL.glGenTextures(1, idMB) ' get the ID from OpenGL
      oglName = idMB.Long(0) ' store the value returned by OpenGL in an integer
      
      ' specify to OpenGL how this texture should be rendered
      
      OpenGL.glBindTexture(OpenGL.GL_TEXTURE_2D, OGLName) ' select the texture id that OpenGL allocated for our texture
      
      OpenGL.glTexParameteri(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_MIN_FILTER, OpenGL.GL_LINEAR) // set up settings
      OpenGL.glTexParameteri(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_MAG_FILTER, OpenGL.GL_LINEAR) // set up some more settings
      
      ' now we load the image bitmap
      
      OpenGL.glTexImage2d(OpenGL.GL_TEXTURE_2D, 0, 4, width, height , 0, OpenGL.GL_RGBA, OpenGL.GL_UNSIGNED_BYTE, RGBABitmap)
      
      return oglName
      
    End Function

    Finally the Render method and RenderModel that is called from it.

    Function Render() Handles Render as Boolean
      OpenGL.glClearColor(1,1,1,1)
      OpenGL.glClear(OpenGL.GL_COLOR_BUFFER_BIT + OpenGL.GL_DEPTH_BUFFER_BIT)
      OpenGL.glPushMatrix
      OpenGL.glTranslatef 0, -0.05, zoom
      
      dim stepSize as double
      dim i, j as integer
      
      
      if model.Ubound = -1 then  return true
      
      X3_SetRotation model(0).Rotation
      
      for i = 0 to model.Ubound
        X3_RenderModel Model(i)
      next
      
      
      
      
      OpenGL.glPopMatrix ' restore matrix
      
      
      
    End Function
    Public Sub X3_RenderModel(model As X3Core.X3Model)
      ' www.Xojo3D.com
      
      Dim i, j As Integer
      Dim poly As X3Core.X3Polygon
      dim col as X3Core.X3Color
      
      if model = nil then return
      
      'X3_SetRotation model.Rotation
      
      if model.visible = false then return
      
      if model.Polygon.Ubound > -1 then
        OpenGL.glBegin OpenGL.GL_TRIANGLES ' start drawing triangle polygons
        openGL.glPolygonMode openGL.GL_FRONT, openGL.GL_FILL
      end if
      ' draw model polygons
      
      for i = 0 to model.Polygon.Ubound ' loop through all the polygons
        
        
        
        poly = model.Polygon(i) ' get the next polygon
        
        ' set the normal of the polygon
        
        OpenGL.glNormal3d poly.Normal.X, poly.Normal.Y, poly.Normal.Z
        
        ' is this polygon mapped with a texture, and if so, is the UV coordinates configured?
        
        'if (poly.TIndex >-1 ) and (poly.UVMap.Ubound >= poly.VIndex.Ubound) then
        if poly.Texture <> nil then
          
          ' yes, a texture is used
          
          OpenGL.glColor4d(1, 1, 1, 1) ' reset color to pure white
          
          OpenGL.glBindTexture(OpenGL.GL_TEXTURE_2D, poly.Texture.OGLName) ' bind to the polygon's texture
          
          ' loop through all the vertexes of the polygon
          
          for j = 0 to poly.VIndex.Ubound
            
            OpenGL.glTexCoord2d poly.UVMap(j).U, poly.UVMap(j).V ' set the texture UV-coordinates for next vertex
            OpenGL.glVertex3d model.Vertex(poly.vindex(j)).X, model.vertex(poly.vindex(j)).Y,model.vertex( poly.vindex(j)).Z ' add the vertex to the OpenGL vertex list
            
          next j
          
          OpenGL.glBindTexture(OpenGL.GL_TEXTURE_2D, 0) ' unbind from the polygon's texture
          
        else
          
          ' set the color of the polygon
          
          if poly.FillColor <> nil then ' is the color object set
            ' yes, so set the color
            OpenGL.glColor4d(poly.FillColor.Red, poly.FillColor.Green, poly.FillColor.Blue, poly.FillColor.Alpha)
          end if
          
          ' loop through all the vertexes of the polygon
          
          for j = 0 to poly.VIndex.Ubound 
            col = model.Vertex( poly.VIndex(j)).pointColor
            if col <> nil then
              openGL.glColor4D( col.Red, col.Green, col.Blue, 1)
            end if
            OpenGL.glVertex3d model.Vertex(poly.vindex(j)).X, model.vertex(poly.vindex(j)).Y,model.vertex( poly.vindex(j)).Z ' add the vertex to the OpenGL vertex list
            
          next j
          
        end if
        
      next i 
      
      OpenGL.glEnd ' end drawing of polygons
      
      
      
      
    End Sub
  15. Michael D

    12 Mar 2018 Pre-Release Testers, Xojo Pro Answer
    Edited 6 months ago

    (Yes, providing a zipped link to the entire project would be helpful).

    I think your problem is that you are making illegal calls between glBegin and glEnd, specifically you are trying to change the bound texture. See https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glBegin.xml which lists the legal commands.

    I think the solution here would be to modify X3_RenderModel so that the glEnd call is at the end of the loop that draws the polys. In other words, after the "next j" statement rather than after the "next i" statement.

  16. Chris H

    12 Mar 2018 Pre-Release Testers, Xojo Pro, XDC Speakers Grand Rapids Michigan

    Michael,

    Tried it before, and again tonight. That didn't do it.
    Yet, I'm positive it's something along this lines. So frustrating.

    Thanks for taking the time to read, review and respond.

  17. Chris H

    12 Mar 2018 Pre-Release Testers, Xojo Pro, XDC Speakers Grand Rapids Michigan

    Michale,

    To make this even worse.....

    If I use the following code only the second texture is ever available.
    ImageA is a blue PNG
    ImageB is a red PNG

    if I set both polygons to texture to the first loaded, nothing shows.
    If I set them both to the second loaded texture, they both show the correct texture.
    If I set one to the first and the second to the second, they both load the second.
    If I set one to the first, and remove the texture and UV coordinates of the second, the second still loads the texture. It's too frustrating!

    Sub Open() Handles Open
      X3_Initialize
      
      Dim m As new X3Core.X3Model()
      dim t1 as new X3Core.X3Texture( imagea ) 
      dim t2 as new X3Core.X3Texture( imageb )
      
      m.Vertex.Append new X3Core.X3Vector( -1, -1, 0 ) // 0
      m.Vertex.Append new X3Core.X3Vector( -1,1,0) // 1
      m.Vertex.Append new X3Core.X3Vector( 1, 1, 0) // 2
      
      m.Vertex.Append new X3Core.X3Vector( 1, -1, 0 ) // 3
      
      dim p as  new X3Core.X3Polygon( 0, 0, 1)
      
      p.VIndex.Append 0
      p.VIndex.Append 2
      p.VIndex.Append 1
      p.UVMap.Append new X3Core.X3UVCoordinate(0,1)
      p.UVMap.Append new X3Core.X3UVCoordinate(1,0)
      p.UVMap.Append new X3Core.X3UVCoordinate(0,0)
      
      p.Texture = t2
      
      m.AppendPolygon p
      
      dim p2 as  new X3Core.X3Polygon( 0, 0, 1)
      p2.VIndex.Append 0
      p2.VIndex.Append 3
      p2.VIndex.Append 2
      p2.UVMap.Append new X3Core.X3UVCoordinate(0,1)
      p2.UVMap.Append new X3Core.X3UVCoordinate(1,1)
      p2.UVMap.Append new X3Core.X3UVCoordinate(1,0)
      
      p2.Texture = t1
      
      m.AppendPolygon p2
      model.Append m
      
      setMyPerspective
      Render
      
      
      
    End Sub
  18. Michael D

    13 Mar 2018 Pre-Release Testers, Xojo Pro

    Hi Chris, I'm pretty sure my answer is the correct one but without a full demo project it's nearly impossible to say what may be going on...

  19. Chris H

    13 Mar 2018 Pre-Release Testers, Xojo Pro, XDC Speakers Grand Rapids Michigan

    Michael, I have zero doubt that you are right! I'm just going to try to dig in and figure it out, hopefully without too much refactoring.
    I may invest the time needed to use the latest version of their X3Core classes.

  20. Chris H

    16 Mar 2018 Pre-Release Testers, Xojo Pro, XDC Speakers Grand Rapids Michigan

    Michael, you were right on the money.

    Thanks!

  21. Newer ›

or Sign Up to reply!