Images are displaying black when I'm not using Graphic 2.0 features and power of 2. Why?

With out seeing some example code that causes the problem, I’d have no idea.  If you’re not getting any errors in your console log… Do you have conditional code (something android only, others Apple only)?  Do you have plugins that you  may be depending on that’s platform specific?

There are no errors in the console log, all plugins for Android are commented out. My apology for not providing anysample codes. Here is the sample code for the game I have in

main.lua 

display.setStatusBar (display.HiddenStatusBar) \_W = display.contentWidth \_H = display.contentHeight local AdCall = false local AdCall2 = false local AdCall3 = false local adX local adY local ShowAd local ShowAd2 local ShowAd3 ads = require "ads" gameNetwork = require ( "gameNetwork" ) targetAppStore = system.getInfo( "targetAppStore" ) --[[--Admob local provider = "admob" local appID = "" if appID == "" then AdCall = false else AdCall = true end --ca-app-pub-5807519691603840/7843687590 if AdCall == true then ads.init( provider, appID ) showAd = function( adType) if targetAppStore == "apple" then adX = 0 adY = 0 else adX = display.screenOriginX adY = display.screenOriginY end ads.show( adType, { x=adX, y=adY } ) end end --]] --[[--iAd for iOS local adNetwork2 = "iads" local appID2 = "com.game.makehimfall" if appID2 == "" then AdCall2 = false else AdCall2 = true end --com.bouncy.ninja if AdCall2 == true then ads.init( adNetwork2, appID2 ) showAd2 = function( adType ) adX = display.contentWidth / 2 adY = 0 ads.show( adType, { x=adX, y=adY, testMode=true } ) end end --]] --[[--Inneractive local adNetwork = "inneractive" local appID3 = "" if appID3 == "" then AdCall3 = false else AdCall3 = true end --TinyLemonGames\_SwingCopter\_iPhone if AdCall3 == true then ads.init( adNetwork, appID3 ) showAd = function( adType ) if targetAppStore == "apple" then adX = 0 adY = 0 else adX = 0 adY = display.screenOriginY end ads.show( adType, { x=adX, y=adY, interval=60, testMode=true } ) -- standard interval for "inneractive" is 60 seconds end end --]] --[[function BannerAdShow() if AdCall == true or AdCall2 == true or AdCall3 == true then --ads.show( "banner" ) end end function BannerAdHide() if AdCall == true or AdCall2 == true or AdCall3 == true then --ads.hide() end end --]] local director = require ("director") local mainGroup = display.newGroup() local function main() mainGroup:insert(director.directorView) \_G.ButtonSFX = audio.loadSound("Click.wav"); \_G.PlayerRotate = audio.loadSound( "playerRotate.mp3" ) \_G.HeadImpact = audio.loadSound( "headImpact.mp3" ) \_G.RowCleared = audio.loadSound( "RowCleared.mp3" ) \_G.backgroundMusic = audio.loadStream("theglutton.mp3") cake = require("cake") character = require("character") buy1 = require("buy1") buy2 = require("buy2") buy3 = require("buy3") buy4 = require("buy4") buy5 = require("buy5") Music = audio.play( backgroundMusic, {loops = -1} ) local function initCallback( event ) if event.type == "showSignIn" then elseif event.data then loggedIntoGC = true end end local function onSystemEvent( event ) if "applicationStart" == event.type then --if targetAppStore == "apple" then loggedIntoGC = false gameNetwork.init( "gamecenter", { listener=initCallback } ) GCLeaderBoardID = "Highfat" --Replace LeaderBoard ID for iOS Game Center --end --if targetAppStore == "google" then --[[gameNetwork.init("google") LeaderBoardID = "" --Google Play LeaderBoard ID -- Tries to login the user, if there is a problem then it will try to resolve it. eg. Show the log in screen. gameNetwork.request("login", { listener = loginListener, userInitiated = true }) --]] --end return true end end Runtime:addEventListener( "system", onSystemEvent ) director:changeScene("menu", "flip") return true end ego = require "ego" saveFile = ego.saveFile loadFile = ego.loadFile main()

menu.lua

module(..., package.seeall) function new() local localGroup = display.newGroup() local character = require("character") local RealHeight = display.actualContentHeight local RealWidth = display.actualContentWidth local isiPad = display.pixelHeight == 1024 local isiPad3 = display.pixelHeight == 2048 local totalWidth = display.contentWidth-(display.screenOriginX\*2); print(totalWidth) local WallLeft local WallRight local object local object2 local Title local Ranking local Rate local Storeit local FirstBox local SecondBox local Home local Character1 local Character2 local Character3 local Character4 local Character5 local Character6 if character.money == nil then character.money = 0 end WallLeft = display.newRect(0,0, 50, RealHeight ) WallLeft.x = display.screenOriginX WallLeft.y = display.contentHeight / 2 WallLeft:setFillColor(0,0,0) localGroup:insert(WallLeft) WallRight = display.newRect(0,0, 50, RealHeight ) WallRight.x = 320 WallRight.y = display.contentHeight / 2 WallRight:setFillColor(0,0,0) localGroup:insert(WallRight) SecondBox = display.newRect(0,0,512,1024) --400, 900 SecondBox.x = display.contentWidth / 2 SecondBox.y = display.contentHeight / 2 display.setDefault( "textureWrapY", "mirroredRepeat" ) SecondBox.fill = { type="image", filename="dirt.png" } local function repeatDirt2() DirtM2 = transition.to( SecondBox.fill, { time=1300, y=SecondBox.fill.y +0.5 , onComplete=repeatTransDirt2 }) end repeatDirt2() localGroup:insert(SecondBox) FirstBox = display.newRect(0,0,512,1024) --400, 900 FirstBox.x = display.contentWidth / 2 FirstBox.y = display.contentHeight / 2 FirstBox.fill = { type="image", filename="dirt.png" } local function repeatTransDirt() DirtM = transition.to( FirstBox.fill, { time=1300, y=FirstBox.fill.y +0.5 , onComplete=repeatTransDirt }) end repeatTransDirt() localGroup:insert(FirstBox) object = display.newRect(0,0, 256, 1024 ) --200, 900 object.x = display.contentWidth \* -0.15 object.y = 100 object.fill = { type="image", filename="wall.png" } local function repeatTrans() object.fill.scaleY = 320/totalWidth F = transition.to( object.fill, { time=1300, y=object.fill.y +0.5, onComplete=repeatTrans }) end repeatTrans() localGroup:insert(object) --display.setDefault( "textureWrapX", "clampToEdge" ) object2 = display.newRect(0,0, 256, 1024 ) --200, 900 object2.x = display.contentWidth \* 1.15 object2.y = 100 object2.fill = { type="image", filename="wall.png" } local function repeatTrans2() object2.fill.scaleY = 320/totalWidth F2 = transition.to( object2.fill, { time=1300, y=object2.fill.y +0.5, onComplete=repeatTrans2 }) end repeatTrans2() localGroup:insert(object2) Title = display.newImage("title.png") Title.x = display.contentWidth / 2 Title.y = display.screenOriginY + 100 localGroup:insert(Title) if character.money == 0 then local GuyOption = { width = 57, height = 88, numFrames = 8, sheetContentWidth = 456, sheetContentHeight = 88 }; GuySheet = graphics.newImageSheet("fatGuy.png", GuyOption); local GuyAnim = { {name = "GuyMoveLeft", frames = {1,2,3,4}, time = 200, loopCount = 0}, {name = "GuyMoveRight", frames = {5,6,7,8}, time = 200, loopCount = 0}, }; Character1 = display.newSprite( GuySheet, GuyAnim) Character1:setSequence("GuyMoveLeft"); Character1:play(); if isiPad or isiPad3 then Character1.x = WallLeft.x + 100 else Character1.x = WallLeft.x + 80 end Character1.y = display.screenOriginY + 200 localGroup:insert(Character1) end if character.money == 1 then local GuyOption2 = { width = 65, height = 88, numFrames = 8, sheetContentWidth = 520, sheetContentHeight = 88 }; GuySheet2 = graphics.newImageSheet("fatGuy2.png", GuyOption2); local GuyAnim2 = { {name = "GuyMoveLeft2", frames = {1,2,3,4}, time = 200, loopCount = 0}, {name = "GuyMoveRight2", frames = {5,6,7,8}, time = 200, loopCount = 0}, }; Character2 = display.newSprite( GuySheet2, GuyAnim2) Character2:setSequence("GuyMoveLeft2"); Character2:play(); Character2.alpha = 0 transition.to(Character2, {time = 100, alpha = 1}) Character2.x = WallLeft.x + 84 Character2.y = display.screenOriginY + 150 localGroup:insert(Character2) end if character.money == 2 then local GuyOption3 = { width = 61, height = 87, numFrames = 8, sheetContentWidth = 488, sheetContentHeight = 87 }; GuySheet3 = graphics.newImageSheet("fatGuy3.png", GuyOption3); local GuyAnim3 = { {name = "GuyMoveLeft3", frames = {1,2,3,4}, time = 200, loopCount = 0}, {name = "GuyMoveRight3", frames = {5,6,7,8}, time = 200, loopCount = 0}, }; Character3 = display.newSprite( GuySheet3, GuyAnim3) Character3:setSequence("GuyMoveLeft3"); Character3:play(); Character3.alpha = 1 Character3.x = WallLeft.x + 81 Character3.y = display.screenOriginY + 150 localGroup:insert(Character3) end if character.money == 3 then local GuyOption4 = { width = 57, height = 88, numFrames = 8, sheetContentWidth = 456, sheetContentHeight = 88 }; GuySheet4 = graphics.newImageSheet("fatGuy4.png", GuyOption4); local GuyAnim4 = { {name = "GuyMoveLeft4", frames = {1,2,3,4}, time = 200, loopCount = 0}, {name = "GuyMoveRight4", frames = {5,6,7,8}, time = 200, loopCount = 0}, }; Character4 = display.newSprite( GuySheet4, GuyAnim4) Character4:setSequence("GuyMoveLeft4"); Character4:play(); Character4.alpha = 1 Character4.x = WallLeft.x + 80 Character4.y = display.screenOriginY + 150 localGroup:insert(Character4) end if character.money == 4 then local GuyOption5 = { width = 58, height = 97, numFrames = 8, sheetContentWidth = 464, sheetContentHeight = 97 }; GuySheet5 = graphics.newImageSheet("fatGuy5.png", GuyOption5); local GuyAnim5 = { {name = "GuyMoveLeft5", frames = {1,2,3,4}, time = 200, loopCount = 0}, {name = "GuyMoveRight5", frames = {5,6,7,8}, time = 200, loopCount = 0}, }; Character5 = display.newSprite( GuySheet5, GuyAnim5) Character5:setSequence("GuyMoveLeft5"); Character5:play(); Character5.alpha = 1 Character5.x = WallLeft.x + 80 Character5.y = display.screenOriginY + 150 localGroup:insert(Character5) end if character.money == 5 then local GuyOption6 = { width = 65, height = 88, numFrames = 8, sheetContentWidth = 520, sheetContentHeight = 88 }; GuySheet6 = graphics.newImageSheet("fatGuy6.png", GuyOption6); local GuyAnim6 = { {name = "GuyMoveLeft6", frames = {1,2,3,4}, time = 200, loopCount = 0}, {name = "GuyMoveRight6", frames = {5,6,7,8}, time = 200, loopCount = 0}, }; Character6 = display.newSprite( GuySheet6, GuyAnim6) Character6:setSequence("GuyMoveLeft6"); Character6:play(); Character6.alpha = 1 Character6.x = WallLeft.x + 84 Character6.y = display.screenOriginY + 150 localGroup:insert(Character6) end ScoreBoard = display.newImageRect("scoreboard.png",190,192) ScoreBoard.x = display.contentWidth / 2 ScoreBoard.y = display.contentHeight \* 0.4 ScoreBoard.alpha = 0 localGroup:insert(ScoreBoard) Storeit = display.newImage("store.png") Storeit.x = ScoreBoard.x + 100 Storeit.y = ScoreBoard.y + 240 localGroup:insert(Storeit) Ranking = display.newImage("rank.png") Ranking.x = ScoreBoard.x - 100 Ranking.y = ScoreBoard.y + 240 localGroup:insert(Ranking) Home = display.newImage("play.png"); Home.x = ScoreBoard.x Home.y = ScoreBoard.y + 240 localGroup:insert(Home) return localGroup end

Hi @sebitttas,

In fact, for texture wrapping modes except “clampToEdge” (the default), you must use power-of-2 textures. This is cautioned in the following document under the “Texture Keys” sub-section:

http://docs.coronalabs.com/api/library/display/setDefault.html

Take care,

Brent

@Brent 

I looked in the link, and that make sense I thought my device was going crazy.

But then when I use “mirroredRepeat” or “repeat” the images for displaying in “display.newImage ( )” for regular images and not for Repeating Fills would display black images when they are not in power of 2. This problem occurs in Apple and not in Android.  

In the code above I presented all the images being displayed would display black when they are not in the power of 2 for Apple. But not for Android. How come?

Hi @sebitttas,

It shouldn’t matter that the images being filled are power-of-2, only the textures filling them. Have you confirmed that this is so?

Brent

@Brent

Yes, I have confirmed that. Also that is the problem I’m facing. My images that are non-texture they display black when I test for Apple, but not for Android device. The only way I can solve the black image is if my all my non-texture are in the power of 2. Which causes them to repear for Apple.

Why does the non-texture images show black for Apple and not for Android when it’s not in the power of 2?

Hi @sebitttas,

I’m not sure what the subtle differences are between the GPUs on the Apple vs. Android devices you’re testing with, but you’ll need to use strictly power-of-2 fill textures. But I thought you already were…

To be 100% clear, with these “black” images on iOS, can you fill any object (any size) with power-of-2 “tiles” and get the proper appearance? Or is it showing up black if these actual filled images are not power-of-2?

Brent

No I cannot fill  any object with power-of-2 “tiles”. It would show black if the actual fill images are not power-of-2.

Hi again @sebitttas,

I think there’s still some misunderstanding…

If you have a vector object, like a display.newRect(), and you fill it with power-of-2 images, it appears black on Apple?

Brent

@Brent

No It’s the opposite if I have a vector, like display.newRect( ), and I don’t fill it with it with power-of-2 images, it appears black on Apple. The same goes if the vector is display.newImage ( ).

No matter what, the images (“tiles”) that you use to fill the parent object must be power-of-2. Am I still missing something?

Yes, regardless the images (“tiles”) that I use to fill the parent object must be power-of-2. No your not missing anything.

I have this exact same problem ; an oddly size image I use as a tappable icon appears first time round, but after that it renders black on Apple only ; in the interim I use an image to tile a background and in the process set textureWrapX and textureWrapY

I would hazard a guess that using either of these causes a different fill routine to be used and the image is actually rendered as a rectangle of the required size filled with a single instance of the image, and this causes the 2^n limitation to click in.