NullPointerException: Cannot invoke "com.badlogic.gdx.Files.external(String)" - nullpointerexception

I'm trying to run a slick 2d example but I get:
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "com.badlogic.gdx.Files.external(String)" because "com.badlogic.gdx.Gdx.files" is null
public class Game extends BasicGame {
private Animation hero, movementUp, movementDown, movementLeft, movementRight, stillUp, stillDown, stillLeft, stillRight;
private Image background;
private char lastDirection;
private float x, y, x2 = 30f, y2 = 25f;
private static final int WIDTH = 640;
private static final int HEIGHT = 480;
private static final float SPEED = 0.1f;
private static final int ANIMATIONSPEED = 500;
TiledMap tiled;
private int maxWidth = 0;
private int maxHeight = 0;
public TmxMapLoader loader ;
public String mapPath="images/map.tmx";
private boolean[][] blocked;
private float mapScale = 1f;
private static final int SIZE = 34;
OrthogonalTiledMapRenderer renderer;
public Game() {
super("Slick2D Animations");
FileHandle map = Gdx.files.external(mapPath );
map.writeString(mapPath,false);
//loader=new TmxMapLoader(new ExternalFileHandleResolver()).load(mapPath);
tiled.getTileSets();
tiled=loader.load(mapPath);
}
The error line is
tiled=loader.load(mapPath)

The solution is to make sure you're not using the gdx library before the create() method in the ApplicationLauncher class. Move the code into the create() method and the problem will be resolved.

Related

my code is only drawing a straight line no matter how many sides i input in the pSides JTextFields

When I input a digit in the JTextfields it should pass through my actionListener to store all the values (ID, number of sides, length of sides and color) into an arraylist. It should then be used in my polygonContainer class that goes through a for loop and a polygon formula, then prints it out. However what comes out all the time is a straight line.
This is the code i tried:
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
public class ContainerFrame extends JFrame{
ArrayList<PolygonContainer> polygons = new ArrayList<>();
// JTextFields for the number of sides, side length, color, and ID
public JTextField pSides, pSidesLengths, pColor, pID;
// Button for submission
public JButton submitButton;
public void createComponents() {
// Initialize the JTextFields
pSides = new JTextField();
pSidesLengths = new JTextField();
pColor = new JTextField();
pID = new JTextField();
submitButton = new JButton("Submit");
submitButton.addActionListener(new ContainerButtonHandler(this));
JPanel textFieldsPanel = new JPanel();
// uses a gridlayout to organise the textfields then sets it as north
textFieldsPanel.setLayout(new GridLayout(5, 2));
textFieldsPanel.add(new JLabel("Sides:"));
textFieldsPanel.add(pSides);
textFieldsPanel.add(new JLabel("Sides Length:"));
textFieldsPanel.add(pSidesLengths);
textFieldsPanel.add(new JLabel("Color:"));
textFieldsPanel.add(pColor);
textFieldsPanel.add(new JLabel("ID:"));
textFieldsPanel.add(pID);
add(textFieldsPanel, BorderLayout.NORTH);
add(submitButton, BorderLayout.SOUTH);
JPanel drawPanel = new ContainerPanel(this);
add(drawPanel, BorderLayout.CENTER);
setSize(1600, 900);
setVisible(true);
setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); // Close action.
}
public static void main(String[] args) {
ContainerFrame cFrame = new ContainerFrame();
cFrame.createComponents();
}
}
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
class ContainerButtonHandler implements ActionListener {
ContainerFrame theApp; // Reference to ContainerFrame object
// ButtonHandler constructor
ContainerButtonHandler(ContainerFrame app) {
theApp = app;
}
public void actionPerformed(ActionEvent e) {
// Get the text from the JTextFields using the getText method
String sides = theApp.pSides.getText();
String sidesLengths = theApp.pSidesLengths.getText();
String id = theApp.pID.getText();
//parse the values as integers
int intSides = Integer.parseInt(sides);
int intSidesLength = Integer.parseInt(sidesLengths);
int intId = Integer.parseInt(id);
//does the input validation where sides, sides length and id needs to be positive integers
if (intId >= 100000 && intId <= 999999 && intSides >= 0 && intSidesLength >= 0) {
// The inputs are valid
String color = theApp.pColor.getText();
// Store the values in an arraylist or other data structure
ArrayList<String> polygonArray = new ArrayList<String>();
polygonArray.add(sides);
polygonArray.add(sidesLengths);
polygonArray.add(color);
polygonArray.add(id);
PolygonContainer polygon = new PolygonContainer(polygonArray);
theApp.polygons.add(polygon);
theApp.repaint();
JOptionPane.showMessageDialog(theApp, "Polygon" + id + "was added to the list.", "Success", JOptionPane.INFORMATION_MESSAGE);
} else {
JOptionPane.showMessageDialog(theApp, "The Polygon" + id + "was not added to the list as a valid Id was not provided.", "Error", JOptionPane.ERROR_MESSAGE);
}
}
}
import java.awt.*;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
public class PolygonContainer implements Comparable<PolygonContainer>{
Color pColor = Color.BLACK; // Colour of the polygon, set to a Colour object, default set to black
int pId = 000000; // Polygon ID should be a six digit non-negative integer
int pSides; // Number of sides of the polygon, should be non-negative value
int pSideLengths; // Length of each side in pixels of the polygon, should be non-negative value
int polyCenX; // x value of centre point (pixel) of polygon when drawn on the panel
int polyCenY; // y value of centre point (pixel of polygon when drawn on the panel
int [] pointsX; // int array containing x values of each vertex (corner point) of the polygon
int [] pointsY; // int array containing y values of each vertex (corner point) of the polygon
// Constructor currently set the number of sides and the equal length of each side of the Polygon
//Constructor that takes the values from the array
public PolygonContainer(ArrayList<String> values){
this.pSides = Integer.parseInt(values.get(0));
this.pSideLengths = Integer.parseInt(values.get(1));
this.pColor = Color.getColor(values.get(2));
this.pId = Integer.parseInt(values.get(3));
pointsX = new int[pSides];
pointsY = new int[pSides];
}
// Used to populate the points array with the vertices corners (points) and construct a polygon with the
// number of sides defined by pSides and the length of each side defined by pSideLength.
// Dimension object that is passed in as an argument is used to get the width and height of the ContainerPanel
// and used to determine the x and y values of its centre point that will be used to position the drawn Polygon.
public Polygon getPolygonPoints(Dimension dim) {
polyCenX = dim.width / 2; // x value of centre point of the polygon
polyCenY = dim.height / 2; // y value of centre point of the polygon
Polygon p = new Polygon();
for (int i = 0; i < pSides; i++) {
// Calculate the x and y coordinates of the ith point of the polygon
int x = polyCenX + pSideLengths * (int) Math.cos(2.0 * Math.PI * i / pSides);
int y = polyCenY + pSideLengths * (int) Math.sin(2.0 * Math.PI * i / pSides);
// Add the x and y coordinates to the pointsX and pointsY arrays
pointsX[i] = x;
pointsY[i] = y;
// Add the point to the polygon object using the addPoint method
p.addPoint(x, y);
}
return p;
}
// You will need to modify this method to set the colour of the Polygon to be drawn
// Remember that Graphics2D has a setColor() method available for this purpose
public void drawPolygon(Graphics2D g, Dimension d) {
//Set color of polygon
g.setColor(pColor);
Polygon p = getPolygonPoints(d);
g.draw(p);
//this creates a bounding box around the polygon
Rectangle2D bounds = p.getBounds2D();
g.draw(bounds);
}
// gets a stored ID
public int getID() {
return pId;
}
#Override
// method used for comparing PolygonContainer objects based on stored ids, you need to complete the method
public int compareTo(PolygonContainer o) {
return 0;
}
// outputs a string representation of the PolygonContainer object, you need to complete this to use for testing
public String toString()
{
return "";
}
}
import javax.swing.JPanel;
import java.awt.*;
public class ContainerPanel extends JPanel{
ContainerFrame conFrame;
public ContainerPanel(ContainerFrame cf) {
conFrame = cf; // reference to ContainerFrame object
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D comp = (Graphics2D)g; // You will need to use a Graphics2D objects for this
Dimension size = getSize(); // You will need to use this Dimension object to get
// the width / height of the JPanel in which the
// Polygon is going to be drawn
for (PolygonContainer polygon : conFrame.polygons) {
polygon.drawPolygon(comp, size);
}
}
}
JFrame

JavaFX: Linking variables correctly for EventHandler (Timeline)

I need to set up a simulation of a nuclear power plant in JavaFX. The GUI is working perfectly, but I've got problems with getting the simulation run. I have to use a Timeline (as EventHandler) for this, the handler updates the radiation value in each cell every single tick. The radiation is displayed as a circle on each cell. The higher the radiation, the bigger should the circle be. For this, I made an if-else-statement.
The problem is: The if-statement cannot access the variables from the EventHandler. But this is necessary to update the circle size each tick. I already tried to put the if-statements right into the EventHandler, but then, no circles have been shown anymore on my GUI.
These are the three classes so far:
EDIT: I put the if-statements into the Event Handler, new code below.
import javafx.application.Application;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
public class NuclearPowerPlant extends Application {
private static final int HEIGHT = 50;
private static final int WIDTH = 55;
private static final int CELL_SIZE = 40;
#Override
public void start(Stage stage) {
stage.setScene(new Scene(createContent()));
stage.show();
}
private Parent createContent() {
Pane root = new Pane();
root.setPrefSize((WIDTH - 40) * CELL_SIZE, (HEIGHT - 40) * CELL_SIZE); // Size of displayed window
for (int y = 0; y < HEIGHT; y++) {
for (int x = 0; x < WIDTH; x++) {
Cell cell = new Cell(x, y);
root.getChildren().add(cell);
}
}
return root;
}
public static void main(String[] args) {
launch(args);
}
}
Cell:
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.input.ContextMenuEvent;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.util.Duration;
public class Cell extends StackPane {
private static final int CELL_SIZE = 40;
int x;
int y;
private Rectangle cell;
private Circle radiation; // Radiation is displayed as a circle
int circlesize; // Size of the circle (the higher the radiation, the bigger the circle)
double radiationvalue = 5000; // Initializing of the radiation value of all cells at the beginning (air in all cells)
private Text symbol; // For Explosion
double activity;
double reflection;
public Cell(int x, int y) { // Konstruktor fuer die Zelle
setTranslateX(x * CELL_SIZE);
setTranslateY(y * CELL_SIZE);
cell = new Rectangle(CELL_SIZE - 2, CELL_SIZE - 2, Color.BLUE);
cell.setStroke(Color.WHITE);
EventHandler<ActionEvent> handlerUpdateRadiationvalue = event -> {
double newradiationvalue = activity + reflection * 500;
// System.out.println(newradiationvalue);
if (newradiationvalue < 1000) {
this.circlesize = 2;
} else if (newradiationvalue >= 1000 && newradiationvalue < 3000) {
this.circlesize = 5;
} else if (newradiationvalue >= 3000 && newradiationvalue < 5000) {
this.circlesize = 8;
} else if (newradiationvalue >= 5000 && newradiationvalue < 7000) {
this.circlesize = 11;
} else if (newradiationvalue >= 7000 && newradiationvalue < 9000) {
this.circlesize = 14;
} else if (newradiationvalue >= 9000 && newradiationvalue < 10000) {
this.circlesize = 18;
}
// Explosion:
else if (newradiationvalue >= 10000) {
circlesize = 0;
cell.setFill(Color.RED);
symbol = new Text("X");
symbol.setFont(Font.font(38));
}
};
KeyFrame keyframe = new KeyFrame(Duration.seconds(0.02), handlerUpdateRadiationvalue);
Timeline tl = new Timeline();
tl.getKeyFrames().addAll(keyframe);
tl.setCycleCount(Timeline.INDEFINITE);
tl.play();
radiation = new Circle(circlesize, Color.BLACK);
getChildren().add(cell);
if (radiationvalue < 10000) {
getChildren().add(radiation);
} else {
getChildren().add(symbol);
}
// Context Menu for material change:
ContextMenu contextMenu = new ContextMenu();
MenuItem air = new MenuItem("Luft");
air.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
activity = Material.AIR.getActivity();
reflection = Material.AIR.getReflection();
cell.setFill(Color.BLUE);
}
});
MenuItem uranium = new MenuItem("Uran");
uranium.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
activity = Material.URANIUM.getActivity();
reflection = Material.URANIUM.getReflection();
cell.setFill(Color.GREEN);
}
});
MenuItem lead = new MenuItem("Blei");
lead.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
activity = Material.LEAD.getActivity();
reflection = Material.LEAD.getReflection();
cell.setFill(Color.GREY);
}
});
MenuItem ruleblock = new MenuItem("Regelblock");
ruleblock.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
activity = Material.RULEBLOCK.getActivity();
reflection = Material.RULEBLOCK.getReflection();
cell.setFill(Color.YELLOW);
}
});
contextMenu.getItems().addAll(air, uranium, lead, ruleblock);
cell.setOnContextMenuRequested(new EventHandler<ContextMenuEvent>() {
#Override
public void handle(ContextMenuEvent event) {
contextMenu.show(cell, event.getScreenX(), event.getScreenY());
}
});
}
ENUM:
public enum Material {
AIR (0, 0.99),
URANIUM (1, 1.12),
LEAD (0, 0.7),
RULEBLOCK (0, 0.99);
double activity;
double reflection;
private Material(double activity, double reflection) {
this.activity = activity;
this.reflection = reflection;
}
double getActivity() {
return activity;
}
public void setActivity(double activity) {
this.activity = activity;
}
double getReflection() {
return reflection;
}
public void setReflection(double reflection) {
this.reflection = reflection;
}
}
The if statement always links to the global variable "radiationvalue" instead of the updated value in the event handler. If I try to access the 'newradiationvalue' in the if statement, I get an error that no such variable can be found (because the one in the Event Handler is not visible from outside).
Maybe someone can tell me how to access the variables in the event handler from outside the event handler?! And if it's not possible: How do I need to change my program to make this work as I want?
Thanks very much in advance!

NAudio - ASIO Playback to device (static only)

I'm trying to route ASIO audio to my playback devices, however, all I hear is static.
ASIO Setup
BIT_PER_SAMPLE = 24
SAMPLE_RATE = 48000
Currently, trying with 1 channel into 1 playback device called "Line 1" for testing. The playback of the sound is static.
EDIT: The code below has been updated. It will take 64 channels of ASIO input and route them one at a time into Waveout devices (I'm using Virtual Audio Cable to create them)
private static AsioOut asioOut;
private static AsioInputPatcher inputPatcher;
private static readonly int BIT_PER_SAMPLE = 16;
private static readonly int SAMPLE_RATE = 48000;
private static readonly int NUMBER_OF_CHANNELS = 64;
private static BufferedWaveProvider[] bufferedWaveProviders = new BufferedWaveProvider[NUMBER_OF_CHANNELS];
private static WaveOut[] waveouts = new WaveOut[NUMBER_OF_CHANNELS];
[STAThread]
static void Main(string[] args)
{
InitDevices();
Record();
while (true)
{
Console.WriteLine("Recording...press any key to Exit.");
Console.ReadKey(true);
break;
}
asioOut.Stop();
asioOut.Dispose();
asioOut = null;
}
private static void Record()
{
inputPatcher = new AsioInputPatcher(SAMPLE_RATE, NUMBER_OF_CHANNELS, NUMBER_OF_CHANNELS);
asioOut = new AsioOut(AsioOut.GetDriverNames()[0]);
asioOut.InitRecordAndPlayback(new SampleToWaveProvider(inputPatcher),
NUMBER_OF_CHANNELS, 0);
asioOut.AudioAvailable += OnAsioOutAudioAvailable;
asioOut.Play();
}
private static void InitDevices()
{
for (int n = -1; n < WaveOut.DeviceCount; n++)
{
WaveOutCapabilities caps = WaveOut.GetCapabilities(n);
if (caps.ProductName.StartsWith("Line"))
{
int _number = int.Parse(caps.ProductName.Split(' ')[1]);
if (_number <= NUMBER_OF_CHANNELS)
{
waveouts[_number - 1] = new WaveOut() { DeviceNumber = n };
bufferedWaveProviders[_number - 1] = new BufferedWaveProvider(new WaveFormat(SAMPLE_RATE, BIT_PER_SAMPLE, 2));
waveouts[_number - 1].Init(bufferedWaveProviders[_number - 1]);
waveouts[_number - 1].Play();
}
}
}
}
static void OnAsioOutAudioAvailable(object sender, AsioAudioAvailableEventArgs e)
{
inputPatcher.ProcessBuffer(e.InputBuffers, e.OutputBuffers,
e.SamplesPerBuffer, e.AsioSampleType);
for (int outputChannel = 0; outputChannel < e.OutputBuffers.Length; outputChannel++)
{
byte[] buf = new byte[e.SamplesPerBuffer * (BIT_PER_SAMPLE / 8)];
Marshal.Copy(e.OutputBuffers[outputChannel], buf, 0, e.SamplesPerBuffer * (BIT_PER_SAMPLE / 8));
bufferedWaveProviders[outputChannel].AddSamples(buf, 0, buf.Length);
}
e.WrittenToOutputBuffers = true;
}
There are two main problems with your code. First, InputBuffers is one per channel, not sample. Second, when you set e.WrittenToOutputBuffers = true you are saying that you have written to e.OutputBuffers which you haven't. So they will just contain uninitialized data.
If you want to see an example of low-level manipulation of ASIO buffers, then check out my ASIO patch bay sample project.

Slow image processing of images from filesystem as compared to the webcam

I was able to follow the csharp-sample-apps from the github repo for Affectiva. I ran the demo using my webcam and the processing and performance was great.I am not getting the same processing speed from the PhotoDetector when I try to run it over images in filesystem. Any help or improvement would be appreciated.
namespace Logical.EmocaoFace
{
public class AnaliseEmocao : Affdex.ImageListener, Affdex.ProcessStatusListener
{
private Bitmap img { get; set; }
private Dictionary<int, Affdex.Face> faces { get; set; }
private Affdex.Detector detector { get; set; }
private ReaderWriterLock rwLock { get; set; }
public void processaEmocaoImagem()
{
for (int i = 0; i < resultado.count; i++){
RetornaEmocaoFace();
if (faceAffdex != null)
{
}
}
}
public void RetornaEmocaoFace(string caminhoImagem)
{
Affdex.Detector detector = new Affdex.PhotoDetector(1, Affdex.FaceDetectorMode.LARGE_FACES);
detector.setImageListener(this);
detector.setProcessStatusListener(this);
if (detector != null)
{
//ProcessVideo videoForm = new ProcessVideo(detector);
detector.setClassifierPath(#"D:\Desenvolvimento\Componentes\Afectiva\data");
detector.setDetectAllEmotions(true);
detector.setDetectAllExpressions(false);
detector.setDetectAllEmojis(false);
detector.setDetectAllAppearances(false);
detector.start();
((Affdex.PhotoDetector)detector).process(LoadFrameFromFile(caminhoImagem));
detector.stop();
}
}
static Affdex.Frame LoadFrameFromFile(string fileName)
{
Bitmap bitmap = new Bitmap(fileName);
// Lock the bitmap's bits.
Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
BitmapData bmpData = bitmap.LockBits(rect, ImageLockMode.ReadWrite, bitmap.PixelFormat);
// Get the address of the first line.
IntPtr ptr = bmpData.Scan0;
// Declare an array to hold the bytes of the bitmap.
int numBytes = bitmap.Width * bitmap.Height * 3;
byte[] rgbValues = new byte[numBytes];
int data_x = 0;
int ptr_x = 0;
int row_bytes = bitmap.Width * 3;
// The bitmap requires bitmap data to be byte aligned.
// http://stackoverflow.com/questions/20743134/converting-opencv-image-to-gdi-bitmap-doesnt-work-depends-on-image-size
for (int y = 0; y < bitmap.Height; y++)
{
Marshal.Copy(ptr + ptr_x, rgbValues, data_x, row_bytes);//(pixels, data_x, ptr + ptr_x, row_bytes);
data_x += row_bytes;
ptr_x += bmpData.Stride;
}
bitmap.UnlockBits(bmpData);
//Affdex.Frame retorno = new Affdex.Frame(bitmap.Width, bitmap.Height, rgbValues, Affdex.Frame.COLOR_FORMAT.BGR);
//bitmap.Dispose();
//return retorno;
return new Affdex.Frame(bitmap.Width, bitmap.Height, rgbValues, Affdex.Frame.COLOR_FORMAT.BGR);
}
public void onImageCapture(Affdex.Frame frame)
{
frame.Dispose();
}
public void onImageResults(Dictionary<int, Affdex.Face> faces, Affdex.Frame frame)
{
byte[] pixels = frame.getBGRByteArray();
this.img = new Bitmap(frame.getWidth(), frame.getHeight(), PixelFormat.Format24bppRgb);
var bounds = new Rectangle(0, 0, frame.getWidth(), frame.getHeight());
BitmapData bmpData = img.LockBits(bounds, ImageLockMode.WriteOnly, img.PixelFormat);
IntPtr ptr = bmpData.Scan0;
int data_x = 0;
int ptr_x = 0;
int row_bytes = frame.getWidth() * 3;
// The bitmap requires bitmap data to be byte aligned.
// http://stackoverflow.com/questions/20743134/converting-opencv-image-to-gdi-bitmap-doesnt-work-depends-on-image-size
for (int y = 0; y < frame.getHeight(); y++)
{
Marshal.Copy(pixels, data_x, ptr + ptr_x, row_bytes);
data_x += row_bytes;
ptr_x += bmpData.Stride;
}
img.UnlockBits(bmpData);
this.faces = faces;
frame.Dispose();
}
public void onProcessingException(Affdex.AffdexException A_0)
{
throw new NotImplementedException("Encountered an exception while processing " + A_0.ToString());
}
public void onProcessingFinished()
{
string idArquivo = CodEspaco + "," + System.Guid.NewGuid().ToString();
for(int i = 0; i < faces.Count; i++)
{
}
}
}
public static class GraphicsExtensions
{
public static void DrawCircle(this Graphics g, Pen pen,
float centerX, float centerY, float radius)
{
g.DrawEllipse(pen, centerX - radius, centerY - radius,
radius + radius, radius + radius);
}
}
}
Found the answer to my own question:
Using PhotoDetector is not ideal in this case since it is expensive to use the Face Detector configuration on subsequent frame calls.
The best option to improve the performance would be to use an instance of the FrameDetector Class.
Here is a getting started guide to analyze-frames.

in libgdx, how to create dynamic texture?

In libgdx, how to create dynamic texture? e.g: create hill or mountain?like the Game
Thank you for your answer, i am waitting for your reply.
Example
=======
package com.badlogic.gdx.tests.bullet;
/**
Question: In libgdx, how to create dynamic texture?
Answer : Use a private render function to draw in a private frame buffer
convert the frame bufder to Pixmap, create Texture.
Author : Jon Goodwin
**/
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Pixmap;
...//(ctrl-shift-o) to auto-load imports in Eclipse
public class BaseBulletTest extends BulletTest
{
//class variables
=================
public Texture texture = null;//create this
public Array<Disposable> disposables = new Array<Disposable>();
public Pixmap pm = null;
//---------------------------
#Override
public void create ()
{
init();
}
//---------------------------
public static void init ()
{
if(texture == null) texture(Color.BLUE, Color.WHITE);
TextureAttribute ta_tex = TextureAttribute.createDiffuse(texture);
final Material material_box = new Material(ta_tex, ColorAttribute.createSpecular(1, 1, 1, 1),
FloatAttribute.createShininess(8f));
final long attributes1 = Usage.Position | Usage.Normal | Usage.TextureCoordinates;
final Model boxModel = modelBuilder.createBox(1f, 1f, 1f, material_box, attributes1);
...
}
//---------------------------
public Texture texture(Color fg_color, Color bg_color)
{
Pixmap pm = render( fg_color, bg_color );
texture = new Texture(pm);//***here's your new dynamic texture***
disposables.add(texture);//store the texture
}
//---------------------------
public Pixmap render(Color fg_color, Color bg_color)
{
int width = Gdx.graphics.getWidth();
int height = Gdx.graphics.getHeight();
SpriteBatch spriteBatch = new SpriteBatch();
m_fbo = new FrameBuffer(Format.RGB565, (int)(width * m_fboScaler), (int)(height * m_fboScaler), false);
m_fbo.begin();
Gdx.gl.glClearColor(bg_color.r, bg_color.g, bg_color.b, bg_color.a);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
Matrix4 normalProjection = new Matrix4().setToOrtho2D(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
spriteBatch.setProjectionMatrix(normalProjection);
spriteBatch.begin();
spriteBatch.setColor(fg_color);
//do some drawing ***here's where you draw your dynamic texture***
...
spriteBatch.end();//finish write to buffer
pm = ScreenUtils.getFrameBufferPixmap(0, 0, (int) width, (int) height);//write frame buffer to Pixmap
m_fbo.end();
// pm.dispose();
// flipped.dispose();
// tx.dispose();
m_fbo.dispose();
m_fbo = null;
spriteBatch.dispose();
// return texture;
return pm;
}
//---------------------------
}//class BaseBulletTest
//---------------------------