SparkyNZ
SparkyNZ

Reputation: 6676

iOS SDL2 OpenGL ES Cannot Draw Texture

I have been trying to follow the below example but using iOS/Xcode instead of VS2015 (which shows an example of an Android cross-platform project).

Youtube Link

I cannot get the code to display any of my texture at all. No matter what I try I only get a small white rectangle. What am I doing wrong?

This should be OpenGL ES1.x so no shaders should be required.

#import <Foundation/Foundation.h>
#include "SDL.h"
#include <time.h>

#include "SDL_opengles.h"

#define FALSE 0
#define TRUE  1

#ifndef BOOL
#define BOOL int
#endif

#define min(a,b)    ((a) < (b) ? (a) : (b))
#define max(a,b)    ((a) > (b) ? (a) : (b))

#define SCREEN_WIDTH  320
#define SCREEN_HEIGHT 480

GLuint g_Texture = 0;

BOOL          g_Running      = TRUE;

SDL_Window    *g_SDLWindow   = NULL;
SDL_Surface   *g_SDLSurface  = NULL;
SDL_Renderer  *g_SDLRenderer = NULL;
SDL_Texture   *g_SDLTexture  = NULL;
int g_ScreenHeight = SCREEN_HEIGHT;
int g_ScreenWidth  = SCREEN_WIDTH;

unsigned char treeData[420] = {
  0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x10, 0x00, 0x10, 0x00, 0x20, 0x08, 0x82, 0x00, 0x00, 0x00, 0x00, 0x01,
  0x16, 0x1D, 0x38, 0xFF, 0x10, 0x50, 0x6C, 0xFF, 0x83, 0x16, 0x1D, 0x38,
  0xFF, 0x00, 0x10, 0x50, 0x6C, 0xFF, 0x82, 0x16, 0x1D, 0x38, 0xFF, 0x82,
  0x00, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x00, 0x81, 0x16, 0x1D,
  0x38, 0xFF, 0x00, 0x10, 0x50, 0x6C, 0xFF, 0x84, 0x16, 0x1D, 0x38, 0xFF,
  0x83, 0x00, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00, 0x82, 0x16,
  0x1D, 0x38, 0xFF, 0x00, 0x10, 0x50, 0x6C, 0xFF, 0x85, 0x00, 0x00, 0x00,
  0x00, 0x85, 0x00, 0x00, 0x00, 0x00, 0x01, 0x16, 0x1D, 0x38, 0xFF, 0x10,
  0x50, 0x6C, 0xFF, 0x81, 0x16, 0x1D, 0x38, 0xFF, 0x85, 0x00, 0x00, 0x00,
  0x00, 0x85, 0x00, 0x00, 0x00, 0x00, 0x83, 0x16, 0x1D, 0x38, 0xFF, 0x85,
  0x00, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00, 0x03, 0x16, 0x1D,
  0x38, 0xFF, 0x10, 0x50, 0x6C, 0xFF, 0x16, 0x1D, 0x38, 0xFF, 0x10, 0x50,
  0x6C, 0xFF, 0x85, 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, 0x00,
  0x89, 0x24, 0xBA, 0x24, 0xFF, 0x82, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00,
  0x00, 0x00, 0x00, 0x87, 0x24, 0xBA, 0x24, 0xFF, 0x00, 0x1A, 0x87, 0x2F,
  0xFF, 0x82, 0x24, 0xBA, 0x24, 0xFF, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x82, 0x24, 0xBA, 0x24, 0xFF, 0x00, 0x1A, 0x87,
  0x2F, 0xFF, 0x81, 0x24, 0xBA, 0x24, 0xFF, 0x00, 0x1A, 0x87, 0x2F, 0xFF,
  0x86, 0x24, 0xBA, 0x24, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8F, 0x24,
  0xBA, 0x24, 0xFF, 0x81, 0x24, 0xBA, 0x24, 0xFF, 0x00, 0x1A, 0x87, 0x2F,
  0xFF, 0x86, 0x24, 0xBA, 0x24, 0xFF, 0x05, 0x1A, 0x87, 0x2F, 0xFF, 0x24,
  0xBA, 0x24, 0xFF, 0x1A, 0x87, 0x2F, 0xFF, 0x24, 0xBA, 0x24, 0xFF, 0x1A,
  0x87, 0x2F, 0xFF, 0x24, 0xBA, 0x24, 0xFF, 0x86, 0x24, 0xBA, 0x24, 0xFF,
  0x00, 0x1A, 0x87, 0x2F, 0xFF, 0x87, 0x24, 0xBA, 0x24, 0xFF, 0x81, 0x24,
  0xBA, 0x24, 0xFF, 0x02, 0x1A, 0x87, 0x2F, 0xFF, 0x24, 0xBA, 0x24, 0xFF,
  0x1A, 0x87, 0x2F, 0xFF, 0x8A, 0x24, 0xBA, 0x24, 0xFF, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x88, 0x24, 0xBA, 0x24, 0xFF, 0x02, 0x1A, 0x87, 0x2F, 0xFF,
  0x24, 0xBA, 0x24, 0xFF, 0x1A, 0x87, 0x2F, 0xFF, 0x81, 0x24, 0xBA, 0x24,
  0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x84,
  0x24, 0xBA, 0x24, 0xFF, 0x00, 0x1A, 0x87, 0x2F, 0xFF, 0x85, 0x24, 0xBA,
  0x24, 0xFF, 0x81, 0x00, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x00,
  0x87, 0x24, 0xBA, 0x24, 0xFF, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x52, 0x55, 0x45, 0x56, 0x49,
  0x53, 0x49, 0x4F, 0x4E, 0x2D, 0x58, 0x46, 0x49, 0x4C, 0x45, 0x2E, 0x00
};


void LoadTree( void )
{
  glGenTextures( 1, &g_Texture );
  glBindTexture( GL_TEXTURE_2D, g_Texture );
  glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, treeData+18 );
}

//--------------------------------------------------------------------------------------------
// InitSDL()
//--------------------------------------------------------------------------------------------
void InitSDL( void )
{
  if( SDL_Init( SDL_INIT_VIDEO ) < 0 )
    exit( -1 );

  atexit( SDL_Quit );

  SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); // *new*

  SDL_DisplayMode currentDisplay;

  SDL_GetCurrentDisplayMode( 0, &currentDisplay );

  g_ScreenWidth  = max( currentDisplay.w, currentDisplay.h );
  g_ScreenHeight = min( currentDisplay.w, currentDisplay.h );

  SDL_DisplayMode displayMode;
  SDL_GetDesktopDisplayMode( 0, &displayMode );
  SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES );

  // PDS: GLES 2 will require shaders etc..
  //SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 2 );
  SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 1 );
  SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 1 );

  g_SDLWindow = SDL_CreateWindow( "Test",
                                 SDL_WINDOWPOS_UNDEFINED,
                                 SDL_WINDOWPOS_UNDEFINED,
                                 g_ScreenWidth,
                                 g_ScreenHeight,
                                 /* SDL_WINDOW_FULLSCFREEN | */ SDL_WINDOW_OPENGL );
  if( g_SDLWindow == NULL )
    exit( -1 );

  SDL_GL_CreateContext( g_SDLWindow );

  glViewport( 0, 0, g_ScreenWidth, g_ScreenHeight );                    // Reset The Current Viewport

  glMatrixMode( GL_PROJECTION );                        // Select The Projection Matrix
  glLoadIdentity();                         // Reset The Projection Matrix

  glRotatef( -90, 0, 0, 1 );

  glOrthof( 0.0f, g_ScreenWidth, g_ScreenHeight, 0.0f, -1.0f, 1.0f );

  glMatrixMode( GL_MODELVIEW );                     // Select The Modelview Matrix
  glLoadIdentity();                         // Reset The Modelview Matrix
  glTranslatef(0.5, 0.5, 0);

  glClearColor( 0.9f, 0.9f, 0.9f, 1.0f );

  glClear( GL_COLOR_BUFFER_BIT );

  LoadTree();

  glShadeModel(GL_SMOOTH);
}


float sq[] =
{
  -7, 7, 0,
  7, 7, 0,
  -7, -7, 0,
  7, -7, 0
};

float tri[] =
{
  sq[ 0 ], sq[ 1 ], sq[ 2 ],
  sq[ 3 ], sq[ 4 ], sq[ 5 ],
  sq[ 6 ], sq[ 7 ], sq[ 8 ],

  sq[ 6 ], sq[ 7 ], sq[ 8 ],
  sq[ 3 ], sq[ 4 ], sq[ 5 ],
  sq[ 9 ], sq[ 10], sq[ 11]
};

float texCoords[]=
{
  0, 1,
  1, 1,
  0, 0,
  0, 0,
  1, 1,
  1, 0
};

//--------------------------------------------------------------------------------------------
// Draw()
//--------------------------------------------------------------------------------------------
void Draw( int x, int y )
{
  glEnable( GL_TEXTURE_2D );

  glMatrixMode( GL_MODELVIEW );

  glLoadIdentity();

  glBindTexture( GL_TEXTURE_2D, g_Texture );

  glPushMatrix();
  glDisable( GL_BLEND );
  glDisable( GL_CULL_FACE );
  glEnable( GL_TEXTURE_2D );

  GLfloat tX = (GLfloat) 10.0f;
  GLfloat tY = (GLfloat) 10.0f;

  GLfloat xOffset = 0;
  GLfloat yOffset = 0;

  // PDS: Offset the drawing by half character width since all placement will be done from quad centre..
  xOffset = tX;
  yOffset = tY;

  glTranslatef( xOffset + x, yOffset + y, 0.0f);

  glEnableClientState( GL_VERTEX_ARRAY );
  glEnableClientState( GL_TEXTURE_COORD_ARRAY );

  glFrontFace( GL_CW );

  glVertexPointer(   3, GL_FLOAT, 0, tri );
  glTexCoordPointer( 2, GL_FLOAT, 0, texCoords );

  glDrawArrays( GL_TRIANGLES, 0, 6 );

  glDisableClientState( GL_TEXTURE_COORD_ARRAY );
  glDisableClientState( GL_VERTEX_ARRAY );
  glDisableClientState( GL_COLOR_ARRAY );

  glPopMatrix();

  glBindTexture( GL_TEXTURE_2D, 0 );
  glEnable( GL_BLEND );
}


//--------------------------------------------------------------------------------------------
// main()
//--------------------------------------------------------------------------------------------
int main( int argc, char* argv[] )
{
  InitSDL();

  SDL_Event     event;

  while( g_Running )
  {
    while( SDL_PollEvent( &event ) )
    {
      switch( event.type )
      {
        case SDL_QUIT:
          g_Running = false;
          break;
      }
    }

    Draw( 100, 100 );

    SDL_GL_SwapWindow( g_SDLWindow );
  }

  SDL_Quit();

  return EXIT_SUCCESS;
} 

Upvotes: 1

Views: 116

Answers (1)

SparkyNZ
SparkyNZ

Reputation: 6676

I figured this out.. The ordering of setting the Projection and ModelView uniforms was wrong - it had to be done after the shader program was in use.. and I had some crazy vertice values for the triangles making up the destination rectangle.

The raw TGA loading didn't work very well either so I went back to my original code for loading TGA files.

The below link contains a working example.

Working Example

Upvotes: 1

Related Questions