I've seen questions about the LWJGL window flickering during rendering, but I'm talking about the full screen flickering here, not just the window. The flickers are ~1.5 seconds long of the normal computer screen, then ~1.5 seconds of full black.
I'm not trying to run the app in full screen.
I'm using the code from this tutorial, that I rewrote in Kotlin:
fun main(args: Array<String>){
SharedLibraryLoader.load()
thread {
Main.run()
}
}
object Main: Runnable {
val window: Long
init {
if (glfwInit() != GL_TRUE)
throw RuntimeException("Couldn't initialize GLFW...")
glfwWindowHint(GLFW_RESIZABLE, GL_TRUE)
window = glfwCreateWindow(800, 600, "Test", NULL, NULL)
if (window == NULL)
throw RuntimeException("Couldn't create the window...")
val videoMode = glfwGetVideoMode(glfwGetPrimaryMonitor())
glfwSetWindowPos(window, 100, 100)
glfwMakeContextCurrent(window)
glfwShowWindow(window)
}
fun update() {
glfwPollEvents()
}
fun render() {
glfwSwapBuffers(window)
}
override fun run() {
while (glfwWindowShouldClose(window) != GL_TRUE){
update()
render()
}
}
}
with the Gradle dependencies:
val lwjglVersion = "3.0.0a"
compile("org.lwjgl:lwjgl:${lwjglVersion}")
compile("org.lwjgl:lwjgl-platform:${lwjglVersion}:natives-windows")
compile("org.lwjgl:lwjgl-platform:${lwjglVersion}:natives-linux")
compile("org.lwjgl:lwjgl-platform:${lwjglVersion}:natives-osx")
I'm on a Debian 9 machine (Linux). Is this a graphics card problem? Or is the code just wrong?
Related
I'm having some issues building out a section of my code which edits server sent thumbnails and renders them as a Google GroundOverlay.
The issue seems to stem from Kotlin Coroutines. First, the documentation from Google says that the ground overlays must be created on the Main Thread. Running their creation out of the main thread causes a fatal error. So I have been sure to make these GroundOverlays on the main thread. When trying to create the bitmap on a thread out of Main, however, I seem to get no overlay at all.
class BarreMapFragment : Fragment(),
GoogleMap.OnCameraIdleListener,
GoogleMap.OnCameraMoveCanceledListener,
GoogleMap.OnCameraMoveListener,
GoogleMap.OnCameraMoveStartedListener,
OnMapReadyCallback {
//Main handler for google map/item styling
googleMapHandler = GoogleMapHandler(gMap!!, activity!!.applicationContext, DefaultTheme, lifecycle.coroutineScope)
. . .
open class GoogleMapHandler(val gMap: GoogleMap,
val context: Context,
val mapThemeInstructions: MapThemeInstructions,
val coroutineScope: CoroutineScope
) {
fun updateActiveUserAvatarPosition(position: LatLng) {
if (mActiveUserAvatar == null) {
coroutineScope.launch {
mActiveUserAvatar = mapObjectFactory.factory(
MapObject(
latitude = position.latitude,
longitude = position.longitude,
objectId = "SELF_AVATAR",
objectType = MapObjectType.USER_AVATAR,
timestamp = System.currentTimeMillis(),
weight = 20.toFloat()
), getOverlayWidthByZoom(dpScreenWidth, gMap.cameraPosition.target, gMap.cameraPosition.zoom)) as RenderedUserAvatarItem
}
}
mActiveUserAvatar?.updatePosition(position)
}
suspend fun factory(mapObject: MapObject, diameter: Float) : RenderedMapItem {
overlayDiameter = diameter
val item = RenderedUserAvatarItem(
mapObject,
buildOverlay(mapObject)
)
return item
}
#MainThread
private suspend fun buildOverlay(mapObject: MapObject) : GroundOverlay {
Log.d("UserOverlay", "I was called.")
//Get the bitmap from the resources
//TODO: We can do more with this later... Like custom avatars
//val bitmap = BitmapFactory.decodeResource(context.resources, R.drawable.ic_user_avatar)
val bitmap = withContext(Dispatchers.Default) {
async {
val d: Drawable = context.getDrawable(R.drawable.ic_user_avatar)!!
val bitmap : Bitmap = drawableToBitmap(d)!!
bitmap
}
}.await()
//val d: Drawable = context.getDrawable(R.drawable.ic_user_avatar)!!
//val bitmap : Bitmap = drawableToBitmap(d)!!
Log.d(TAG, "bitmap = " + bitmap.toString())
//Make bitmap descriptor
val descriptor = BitmapDescriptorFactory.fromBitmap(bitmap)
val overlayOptions = GroundOverlayOptions().image(descriptor)
//Position and size of groundoverlay
overlayOptions.position(LatLng(mapObject.latitude, mapObject.latitude) , overlayDiameter)
//Add the overlay to the map, get a handle and save it to public Overlay list
val mOverlay = gMap.addGroundOverlay(overlayOptions)
//Store the moment information in the overlay tag
mOverlay.tag = mapObject.objectId
return mOverlay
}
The suspend function is called from the main thread. Now,
val bitmap = withContext(Dispatchers.Unconfined) {
async {
val d: Drawable = context.getDrawable(R.drawable.ic_user_avatar)!!
val bitmap : Bitmap = drawableToBitmap(d)!!
bitmap
}
}.await()
and the commented out section above (without using async)
val d: Drawable = context.getDrawable(R.drawable.ic_user_avatar)!!
val bitmap : Bitmap = drawableToBitmap(d)!!
Will both yield a GroundOverlay with no problems. The problem happens when I change Dispatchers.Unconfined to anything else. Even Dispatchers.Main causes the GroundOverlay to not show up on the map. The GroundOverlays are made, I have checked them with log statements. Their transparency is expected as is their visibility. The issue seems to be with the Bitmap. I suspect I am not understanding the way the await() works. I figured that it would pause the suspend function until the bitmap is returned and ready to go.
This is simplified code to isolate the error. I do need this to be done on Dispatchers.Default because each thumbnail is adjusted in style depending on the location and time of day. This bit of processing would be hard on the UI if done on the main thread.
I have a custom UIStoryboardSegue that works as desired in iOS12.*.
One of the destination view controller is a UITabbarController: for each tab, I have a controller embedded in a navigation controller.
Unfortunately, for iOS13.*, this does not work well: the view controller lifecycle is broken, and no call the viewXXXAppear() nor the willTransition() methods are no longer issued.
It looks like makeKeyAndVisible() has no effect?!
See at the bottom how the screen UI is puzzled below without viewWillAppear() being called.
An horrible temporary workaround
I had to pull my hairs but, I have found a fix which I make public (I had to add a navigation controller on the fly).
This messes the vc hierarchy: do you have a better solution?
public class AladdinReplaceRootViewControllerSegue: UIStoryboardSegue {
override public func perform() {
guard let window = UIApplication.shared.delegate?.window as? UIWindow,
let sourceView = source.view,
let destinationView = destination.view else {
super.perform()
return
}
let screenWidth = UIScreen.main.bounds.size.width
let screenHeight = UIScreen.main.bounds.size.height
destinationView.frame = CGRect(x: 0, y: 0, width: screenWidth, height: screenHeight)
window.insertSubview(destinationView, aboveSubview: sourceView)
// **My fix**
if #available(iOS 13,*) {
// I introduced an invisible navigation controller starting in iOS13 otherwise, my controller attached to the tabbar thru a navigation, dont work correctly, no viewXAppearis called.
let navigationController = UINavigationController.init(rootViewController: self.destination)
navigationController.isNavigationBarHidden = true
window.rootViewController = navigationController
}
else {
window.rootViewController = self.destination
}
window.makeKeyAndVisible()
}
}
I found a solution thanks to Unbalanced calls to begin/end appearance transitions with custom segue
What happens here is that the creation and attaching of the destination view controller happens twice, and the first one happens too soon.
So what you need to do is:
public class AladdinReplaceRootViewControllerSegue: UIStoryboardSegue {
override public func perform() {
guard let window = UIApplication.shared.delegate?.window as? UIWindow,
let sourceView = source.view,
let destinationView = destination.view else {
super.perform()
return
}
let screenWidth = UIScreen.main.bounds.size.width
let screenHeight = UIScreen.main.bounds.size.height
let mock = createMockView(view: desination.view)
window.insertSubview(mock, aboveSubview: sourceView)
//DO SOME ANIMATION HERE< MIGHT NEED TO DO mock.alpha = 0
//after the animation is done:
window.rootViewController = self.destination
mock.removeFromSuperview()
}
func createMockView(view: UIView) -> UIImageView {
UIGraphicsBeginImageContextWithOptions(view.frame.size, true, UIScreen.main.scale)
view.drawHierarchy(in: view.bounds, afterScreenUpdates: true)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return UIImageView(image: image)
}
}
I had a similar problem on iOS 13 when performing a custom storyboard segue that replaces the rootViewController. The original code looked like this:
#interface CustomSegue : UIStoryboardSegue
#end
#implementation CustomSegue
- (void)perform {
AppDelegate* appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
UIViewController *destination = (UIViewController *) self.destinationViewController;
[destination.view removeFromSuperview];
[appDelegate.window addSubview:destination.view];
appDelegate.window.rootViewController = destination;
}
#end
Removing the line [appDelegate.window addSubview:destination]; fixed the problem to me. Apparanently, it was unnecessary to add the new VC's view as a subview to the window. It did the job correctly even after removing that line, and it also fixed the error message "unbalanced calls to begin/end appearance transitions".
Today I'm using Android Intent in the following format to trigger navigation from my application on standalone navigation applications:
Action : "android.intent.action.VIEW"
URI : "google.navigation:q=48.605086,2.367014/48.607231,2.356997"
Component Name of the navigation app : For example Google Maps "com.google.android.apps.maps/com.google.android.maps.MapsActivity"
For example:
Intent mapIntent = new Intent(Intent.ACTION_VIEW, gmmIntentUri);
mapIntent.setPackage("com.google.android.apps.maps");
startActivity(mapIntent);
from : https://developers.google.com/maps/documentation/urls/android-intents
I want to trigger navigation with multiple way points, Is it possible on TomTom Go Mobile, Google Maps, Waze, Here WeGo and Sygic via Intent ?
Can I trigger navigation on the application above and start driving automatically? Without user interaction ?
I tried to trigger the above intent via ADB and do some tweaking by adding "," , ";", "and". Nothing worked.
In order to open the navigation mode in the HERE WeGo app you can use the following function
private fun navigateToDestination(destination: GeoCoordinate) {
try {
val intent = Intent().apply {
action = "com.here.maps.DIRECTIONS"
addCategory(Intent.CATEGORY_DEFAULT)
data = Uri.parse("here.directions://v1.0/mylocation/${destination.latitude},${destination.longitude}")
}
intent.resolveActivity(packageManager)?.let {
startActivity(intent)
}
} catch (t: Throwable) {
Timber.e(t)
}
}
Sygic:
private fun navigateToDestination(destination: GeoCoordinate) {
try {
val intent = Intent(Intent.ACTION_VIEW, Uri.parse("com.sygic.aura://coordinate|${destination.longitude}|${destination.latitude}|drive"))
intent.resolveActivity(packageManager)?.let {
startActivity(intent)
}
} catch (t: Throwable) {
Timber.e(t)
}
}
Waze:
private fun navigateToDestination(destination: GeoCoordinate) {
try {
val intent = Intent(Intent.ACTION_VIEW, Uri.parse("waze://?ll=${destination.latitude}, ${destination.longitude}&navigate=yes"))
intent.resolveActivity(packageManager)?.let {
startActivity(intent)
}
} catch (t: Throwable) {
Timber.e(t)
}
}
You can also resolve the installed apps that can be used for navigation and let the user decide which one s/he wants to use:
private fun navigateToDestination(destination: GeoCoordinate) {
try {
val intent = Intent(Intent.ACTION_VIEW, Uri.parse("google.navigation:q=${destination.latitude}, ${destination.longitude}"))
val resolvedPackages = packageManager.queryIntentActivities(intent, PackageManager.MATCH_ALL)
if (resolvedPackages.isNotEmpty()) {
val packageNames = resolvedPackages.map { it.activityInfo.packageName }
val targetIntents = packageNames.map { packageManager.getLaunchIntentForPackage(it) }
val intentChooser = Intent.createChooser(Intent(), "Choose a navigation app")
intentChooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetIntents.toTypedArray())
startActivity(intentChooser)
}
} catch (t: Throwable) {
Timber.e(t)
}
}
I have a Letter class like this:
class Letter : Label {
val char: Char
var interactable = true
constructor(char: Char) : super(""+char, H.letterStyle()) {
this.char = char
}
fun animateSelect() {
addAction(Actions.scaleTo(3.0f, 3.0f, 0.5f))
}
fun animateUnselect() {
addAction(Actions.scaleTo(3.0f, 3.0f, 0.5f))
}
}
In my touch listener, I have this:
override fun touchDown(event: InputEvent?, x: Float, y: Float, pointer: Int, button: Int): Boolean {
var currentInteractingLetter: Letter? = null
for (letter in letterList) {
if (letter.bound.contains(x, y)) {
currentInteractingLetter = letter
break
}
}
if (currentInteractingLetter == null) {
} else {
selectedLetters.add(currentInteractingLetter)
currentInteractingLetter.animateSelect()
currentInteractingLetter.interactable = false
}
return true
}
The logic is quite straightforward. When user touch any one of the letters, I will invoke animateSelect() function.
When I run it, animateSelect did get called, but there is no scaleUp effect. I have tried to clear all actions before addAction but still the same.
Labels don't directly support scaling.
The easy way to solve this is put the label in a Container, setTransform(true) on the Container, and add your scale action to the Container.
val container= Container<Label>().apply {
isTransform=true
actor=label // Set your Label to container
}
container.addAction(Actions.scaleTo(3.0f, 3.0f, 0.5f))
I'm writing a small application in scala. The application processes simple log files. Because the processing takes some time, I've decided to let my application core extend Actor.
class Application extends Actor {
def react() {
loop {
react {
case Process(file) => // do something interesting with file...
}
}
}
}
The processing of a log file is triggered by clicking a button in the gui. The gui uses scala swing.
object Gui extends SimpleSwingApplication {
val application = new Application().start()
def top = new MainFrame {
val startButton = new Button
reactions += {
case ButtonClicked(`startButton`) => application ! Process(file)
}
}
}
Now, the application core needs to notify the gui about the current progress.
sender ! Progress(value) // whenever progress is made
I've solved this by creating a separate actor inside the gui. The actor is executed inside the edt thread. It listens to messages from the application core and updates the gui.
object Gui extends SimpleSwingApplication {
val actor = new Actor {
override val scheduler = new SchedulerAdapter {
def execute(fun: => Unit) { Swing.onEDT(fun) }
}
start()
def act() {
loop {
react {
case ForwardToApplication(message) => application ! message
case Progress(value) => progressBar.value = value
}
}
}
}
}
Since the application core needs to know about the sender of the message, I also use this actor to forward messages from the gui to the application core, making my actor the new sender.
reactions += {
case ButtonClicked(`startButton`) => actor ! ForwardToApplication(Process(file))
}
This code works just fine. My question: Is there a simpler way to do this? It whould be nice to simple use the reactions mechanism for my application messages:
reactions += {
case Progress(value) => progressBar.value = value
}
Any ideas how to achieve this?
I have extended on gerferras idea of making my application a swing.Publisher. The following class acts as intermediator between a swing.Reactor and an Actor.
import actors.Actor
import swing.Publisher
import swing.event.Event
import swing.Swing.onEDT
case class Send(event: Any)(implicit intermediator: Intermediator) {
intermediator ! this
}
case class Receive(event: Any) extends Event
case class Intermediator(application: Actor) extends Actor with Publisher {
start()
def act() {
loop {
react {
case Send(evt) => application ! evt
case evt => onEDT(publish(Receive(evt)))
}
}
}
}
Now my reactions can include both swing events and application events.
implicit val intermediator = Intermediator(application)
listenTo(intermediator, button)
reactions += {
case ButtonClicked(`button`) => Send(Process(file))
case Receive(Progress(value)) => progressBar.value = value
}
Note how the case class Send provides some syntactic sugar to easily create events and pass them to the intermediator.
Maybe this is simpler but don't know if it's better. Instead of making your application backend an actor, you can create an anonymous actor every time you need to process the file:
reactions += {
case ButtonClicked(`startButton`) => application.process(file, { v: Int => Swing.onEDT(progressBar.value = v) })
}
For the progress update part, you can pass a callback to the process method to be executed every time a new progress is made:
import scala.actors.Actor.actor
def process(f: File, progress: Int => Unit) {
actor {
// process file while notifying the progress using the callback
progress(n)
}
}
Alternatively (haven't tested) you could make your application a scala.swing.Publisher and, instead of using the callback, publish and event every time. So the code could be:
listenTo(startButton, application) //application is a Publisher
reactions += {
case ButtonClicked(`startButton`) => application.process(file)
case Progress(v) => progressBar.value = v
}
And in the application:
import scala.actors.Actor.actor
def process(f: File) {
actor {
// process file while notifying the progress using an scala.swing.event.Event
publish(Progess(n))
}
}