Third Person Camera using JBullet and lwjgl - java
I am developing a race game in java using jbullet and lwjgl.I am currently having trouble in making my camera follow the vehicle.Here is my code.It follows the car until it rotates.Here is the code.Can someone tell me what i am doing wrong ?!
import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT;
import static org.lwjgl.opengl.GL11.GL_DEPTH_BUFFER_BIT;
import static org.lwjgl.opengl.GL11.GL_FRONT_AND_BACK;
import static org.lwjgl.opengl.GL11.GL_LINE;
import static org.lwjgl.opengl.GL11.GL_QUADS;
import static org.lwjgl.opengl.GL11.glBegin;
import static org.lwjgl.opengl.GL11.glCallList;
import static org.lwjgl.opengl.GL11.glClear;
import static org.lwjgl.opengl.GL11.glColor3f;
import static org.lwjgl.opengl.GL11.glEnd;
import static org.lwjgl.opengl.GL11.glLoadIdentity;
import static org.lwjgl.opengl.GL11.glPolygonMode;
import static org.lwjgl.opengl.GL11.glPopMatrix;
import static org.lwjgl.opengl.GL11.glPushMatrix;
import static org.lwjgl.opengl.GL11.glTranslated;
import static org.lwjgl.opengl.GL11.*;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.vecmath.Matrix4f;
import javax.vecmath.Quat4f;
import javax.vecmath.Vector3f;
import model.Vehicle;
import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import utility.LWJGLTimer;
import utility.LookAtCamera;
import utility.Model;
import utility.OBJLoader;
import utility.TerrainLoader;
import com.bulletphysics.collision.broadphase.BroadphaseInterface;
import com.bulletphysics.collision.broadphase.DbvtBroadphase;
import com.bulletphysics.collision.dispatch.CollisionConfiguration;
import com.bulletphysics.collision.dispatch.CollisionDispatcher;
import com.bulletphysics.collision.dispatch.CollisionObject;
import com.bulletphysics.collision.dispatch.CollisionWorld;
import com.bulletphysics.collision.dispatch.DefaultCollisionConfiguration;
import com.bulletphysics.collision.shapes.BoxShape;
import com.bulletphysics.collision.shapes.CollisionShape;
import com.bulletphysics.collision.shapes.SphereShape;
import com.bulletphysics.collision.shapes.StaticPlaneShape;
import com.bulletphysics.dynamics.DiscreteDynamicsWorld;
import com.bulletphysics.dynamics.DynamicsWorld;
import com.bulletphysics.dynamics.RigidBody;
import com.bulletphysics.dynamics.RigidBodyConstructionInfo;
import com.bulletphysics.dynamics.constraintsolver.SequentialImpulseConstraintSolver;
import com.bulletphysics.linearmath.DefaultMotionState;
import com.bulletphysics.linearmath.Transform;
public class PlanoFight {
private static LookAtCamera camera;
Vector3f position = new Vector3f(0, 0, 0);
private DynamicsWorld dynamicsWorld = null;
public PlanoFight() {
setUpDisplay();
setUpCamera();
setUpDisplayLists();
setUpPhysics();
initializeGL();
startGameLoop();
}
private void setUpDisplayLists() {
}
Vehicle vehicle;
private void startGameLoop() {
LWJGLTimer timer = new LWJGLTimer();
double delta = 0;
timer.initialize();
while (!Display.isCloseRequested()) {
timer.update();
delta = timer.getElapsedTime();
dynamicsWorld.stepSimulation(1f / 60f, 10);
checkInput();
update(delta);
render();
Display.update();
Display.sync(60);
}
cleanup();
Display.destroy();
System.exit(0);
}
private void cleanup() {
}
private void initializeGL() {
}
private void setUpDisplay() {
try {
Display.setDisplayMode(new DisplayMode(800, 600));
Display.create();
} catch (LWJGLException e) {
e.printStackTrace();
Display.destroy();
System.exit(0);
}
}
private void update(double delta) {
vehicle.update();
}
private void render() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
vehicle.updateCamera(camera);
camera.setMatrices();
vehicle.render();
}
public static void main(String ar[]) {
new PlanoFight();
}
private static void setUpCamera() {
camera = new LookAtCamera(67, 100f, 0.1f, (float) (Display.getWidth() / Display.getHeight()));
camera.setPosition(new Vector3f(0,5,0));
}
private void checkInput() {
if (Keyboard.isKeyDown(Keyboard.KEY_DOWN)) {
vehicle.deacelerate();
} else if (Keyboard.isKeyDown(Keyboard.KEY_UP)) {
vehicle.accelerate();
} else if (Keyboard.isKeyDown(Keyboard.KEY_LEFT)) {
vehicle.steerLeft();
} else if (Keyboard.isKeyDown(Keyboard.KEY_RIGHT)) {
vehicle.steerRight();
}
}
private void setUpPhysics() {
BroadphaseInterface bInterface = new DbvtBroadphase();
CollisionConfiguration configuration = new DefaultCollisionConfiguration();
CollisionDispatcher dispather = new CollisionDispatcher(configuration);
SequentialImpulseConstraintSolver solver = new SequentialImpulseConstraintSolver();
dynamicsWorld = new DiscreteDynamicsWorld(dispather, bInterface, solver, configuration);
dynamicsWorld.setGravity(new Vector3f(0, -10, 0));
vehicle=new Vehicle(dynamicsWorld);
}
}
package model;
import static org.lwjgl.opengl.GL11.GL_QUADS;
import static org.lwjgl.opengl.GL11.glBegin;
import static org.lwjgl.opengl.GL11.glCallList;
import static org.lwjgl.opengl.GL11.glColor3f;
import static org.lwjgl.opengl.GL11.glEnd;
import static org.lwjgl.opengl.GL11.glMultMatrix;
import static org.lwjgl.opengl.GL11.glPopMatrix;
import static org.lwjgl.opengl.GL11.glPushMatrix;
import static org.lwjgl.opengl.GL11.glRotated;
import static org.lwjgl.opengl.GL11.glTranslatef;
import static org.lwjgl.opengl.GL11.glVertex3f;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import javax.vecmath.Vector3f;
import org.lwjgl.BufferUtils;
import org.lwjgl.util.glu.Cylinder;
import utility.LookAtCamera;
import utility.Model;
import utility.OBJLoader;
import com.bulletphysics.collision.broadphase.BroadphaseInterface;
import com.bulletphysics.collision.dispatch.CollisionDispatcher;
import com.bulletphysics.collision.dispatch.CollisionObject;
import com.bulletphysics.collision.dispatch.DefaultCollisionConfiguration;
import com.bulletphysics.collision.shapes.BoxShape;
import com.bulletphysics.collision.shapes.CollisionShape;
import com.bulletphysics.collision.shapes.CompoundShape;
import com.bulletphysics.collision.shapes.TriangleIndexVertexArray;
import com.bulletphysics.dynamics.DynamicsWorld;
import com.bulletphysics.dynamics.RigidBody;
import com.bulletphysics.dynamics.RigidBodyConstructionInfo;
import com.bulletphysics.dynamics.constraintsolver.ConstraintSolver;
import com.bulletphysics.dynamics.vehicle.DefaultVehicleRaycaster;
import com.bulletphysics.dynamics.vehicle.RaycastVehicle;
import com.bulletphysics.dynamics.vehicle.VehicleRaycaster;
import com.bulletphysics.dynamics.vehicle.VehicleTuning;
import com.bulletphysics.dynamics.vehicle.WheelInfo;
import com.bulletphysics.linearmath.DefaultMotionState;
import com.bulletphysics.linearmath.Transform;
import com.bulletphysics.util.ObjectArrayList;
public class Vehicle {
private static final int rightIndex = 0;
private static final int upIndex = 1;
private static final int forwardIndex = 2;
private static final Vector3f wheelDirectionCS0 = new Vector3f(0, -1, 0);
private static final Vector3f wheelAxleCS = new Vector3f(-1, 0, 0);
private static float gEngineForce = 0.f;
private static float gBreakingForce = 0.f;
private static float maxEngineForce = 1000.f;// this should be
// engine/velocity dependent
private static float maxBreakingForce = 100.f;
private static float gVehicleSteering = 0.f;
private static float steeringIncrement = 0.04f;
private static float steeringClamp = 0.3f;
private static float wheelRadius = 0.5f;
private static float wheelWidth = 0.4f;
private static float wheelFriction = 1000;// 1e30f;
private static float suspensionStiffness = 20.f;
private static float suspensionDamping = 2.3f;
private static float suspensionCompression = 4.4f;
private static float rollInfluence = 0.1f;// 1.0f;
private static final float suspensionRestLength = 0.6f;
private static final int CUBE_HALF_EXTENTS = 1;
public RigidBody carChassis;
public ObjectArrayList<CollisionShape> collisionShapes = new ObjectArrayList<CollisionShape>();
public BroadphaseInterface overlappingPairCache;
public CollisionDispatcher dispatcher;
public ConstraintSolver constraintSolver;
public DefaultCollisionConfiguration collisionConfiguration;
public TriangleIndexVertexArray indexVertexArrays;
public ByteBuffer vertices;
public VehicleTuning tuning = new VehicleTuning();
public VehicleRaycaster vehicleRayCaster;
public RaycastVehicle vehicle;
public float cameraHeight;
public float minCameraDistance;
public float maxCameraDistance;
private DynamicsWorld dynamicsWorld;
private Cylinder cylinder;
private int carChassisHandle;
Vector3f direction;
public Vehicle(DynamicsWorld world) {
this.dynamicsWorld = world;
carChassis = null;
cameraHeight = 4f;
minCameraDistance = 3f;
maxCameraDistance = 10f;
indexVertexArrays = null;
vertices = null;
vehicle = null;
cylinder = new Cylinder();
direction = new Vector3f(0, 0, -1);
initPhysics();
try {
Model model = OBJLoader.loadModel(new File("res/chassis.obj"));
carChassisHandle = OBJLoader.createDisplayList(model);
} catch (IOException e) {
e.printStackTrace();
}
}
public void initPhysics() {
CollisionShape groundShape = new BoxShape(new Vector3f(50, 3, 50));
collisionShapes.add(groundShape);
Transform tr = new Transform();
tr.setIdentity();
tr.origin.set(0, -4.5f, 0);
localCreateRigidBody(0, tr, groundShape);
CollisionShape chassisShape = new BoxShape(new Vector3f(1.0f, 0.5f, 2.0f));
collisionShapes.add(chassisShape);
CompoundShape compound = new CompoundShape();
collisionShapes.add(compound);
Transform localTrans = new Transform();
localTrans.setIdentity();
localTrans.origin.set(0, 1, 0);
compound.addChildShape(localTrans, chassisShape);
tr.origin.set(0, 0, 0);
carChassis = localCreateRigidBody(800, tr, compound);
Transform t = new Transform();
carChassis.getWorldTransform(t);
Vector3f forward = new Vector3f();
t.basis.getRow(0, forward);
System.out.println("0 " + forward);
t.basis.getRow(1, forward);
System.out.println("1 " + forward);
t.basis.getRow(2, forward);
System.out.println("2 " + forward);
clientResetScene();
// create vehicle
{
vehicleRayCaster = new DefaultVehicleRaycaster(dynamicsWorld);
vehicle = new RaycastVehicle(tuning, carChassis, vehicleRayCaster);
// never deactivate the vehicle
carChassis.setActivationState(CollisionObject.DISABLE_DEACTIVATION);
dynamicsWorld.addVehicle(vehicle);
float connectionHeight = 1.2f;
boolean isFrontWheel = true;
vehicle.setCoordinateSystem(rightIndex, upIndex, forwardIndex);
Vector3f connectionPointCS0 = new Vector3f(CUBE_HALF_EXTENTS - (0.3f * wheelWidth), connectionHeight, 2f * CUBE_HALF_EXTENTS - wheelRadius);
vehicle.addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, tuning, isFrontWheel);
connectionPointCS0.set(-CUBE_HALF_EXTENTS + (0.3f * wheelWidth), connectionHeight, 2f * CUBE_HALF_EXTENTS - wheelRadius);
vehicle.addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, tuning, isFrontWheel);
connectionPointCS0.set(-CUBE_HALF_EXTENTS + (0.3f * wheelWidth), connectionHeight, -2f * CUBE_HALF_EXTENTS + wheelRadius);
isFrontWheel = false;
vehicle.addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, tuning, isFrontWheel);
connectionPointCS0.set(CUBE_HALF_EXTENTS - (0.3f * wheelWidth), connectionHeight, -2f * CUBE_HALF_EXTENTS + wheelRadius);
vehicle.addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, tuning, isFrontWheel);
for (int i = 0; i < vehicle.getNumWheels(); i++) {
WheelInfo wheel = vehicle.getWheelInfo(i);
wheel.suspensionStiffness = suspensionStiffness;
wheel.wheelsDampingRelaxation = suspensionDamping;
wheel.wheelsDampingCompression = suspensionCompression;
wheel.frictionSlip = wheelFriction;
wheel.rollInfluence = rollInfluence;
}
}
}
public void render() {
float matrix[] = new float[16];
glColor3f(0, 0, 1);
glBegin(GL_QUADS);
glVertex3f(100, -4.5f, 100);
glVertex3f(100, -4.5f, -100);
glVertex3f(-100, -4.5f, -100);
glVertex3f(-100, -4.5f, 100);
glEnd();
FloatBuffer buffer;
Transform chassisTr = new Transform();
carChassis.getMotionState().getWorldTransform(chassisTr);
CollisionShape chassisShape = carChassis.getCollisionShape();
if (chassisShape instanceof CompoundShape) {
CollisionShape childShape = ((CompoundShape) chassisShape).getChildShape(0);
if (childShape instanceof BoxShape) {
Vector3f size = new Vector3f();
((BoxShape) childShape).getHalfExtentsWithoutMargin(size);
System.out.println(size.x + " " + size.y + " " + size.z);
System.out.println(chassisTr.origin.x + " " + chassisTr.origin.y + " " + chassisTr.origin.z);
}
}
chassisTr.getOpenGLMatrix(matrix);
buffer = BufferUtils.createFloatBuffer(16 * 4);
buffer.clear();
buffer.put(matrix);
buffer.flip();
glColor3f(0, 1, 0);
glPushMatrix();
glMultMatrix(buffer);
glTranslatef(0, 1f, 0);
glCallList(carChassisHandle);
glPopMatrix();
for (int i = 0; i < vehicle.getNumWheels(); i++) {
vehicle.updateWheelTransform(i, true);
Transform wheelTr = vehicle.getWheelInfo(i).worldTransform;
wheelTr.getOpenGLMatrix(matrix);
buffer = BufferUtils.createFloatBuffer(16 * 4);
buffer.clear();
buffer.put(matrix);
buffer.flip();
glColor3f(1, 0, 0);
glPushMatrix();
glMultMatrix(buffer);
glRotated(90, 0, 1, 0);
cylinder.draw(wheelRadius, wheelRadius, wheelWidth, 10, 10);
glPopMatrix();
}
}
public void update() {
int wheelIndex = 2;
vehicle.applyEngineForce(gEngineForce, wheelIndex);
vehicle.setBrake(gBreakingForce, wheelIndex);
wheelIndex = 3;
vehicle.applyEngineForce(gEngineForce, wheelIndex);
vehicle.setBrake(gBreakingForce, wheelIndex);
wheelIndex = 0;
vehicle.setSteeringValue(gVehicleSteering, wheelIndex);
wheelIndex = 1;
vehicle.setSteeringValue(gVehicleSteering, wheelIndex);
}
public void clientResetScene() {
gVehicleSteering = 0f;
Transform tr = new Transform();
tr.setIdentity();
carChassis.setCenterOfMassTransform(tr);
carChassis.setLinearVelocity(new Vector3f(0, 0, 0));
carChassis.setAngularVelocity(new Vector3f(0, 0, 0));
dynamicsWorld.getBroadphase().getOverlappingPairCache().cleanProxyFromPairs(carChassis.getBroadphaseHandle(), dynamicsWorld.getDispatcher());
if (vehicle != null) {
vehicle.resetSuspension();
for (int i = 0; i < vehicle.getNumWheels(); i++) {
vehicle.updateWheelTransform(i, true);
}
}
}
public void steerLeft() {
System.out.println("steer left");
gVehicleSteering += steeringIncrement;
if (gVehicleSteering > steeringIncrement) {
gVehicleSteering = steeringClamp;
}
}
public void steerRight() {
gVehicleSteering -= steeringIncrement;
if (gVehicleSteering < -steeringClamp)
gVehicleSteering = -steeringClamp;
}
public void accelerate() {
gEngineForce = maxEngineForce;
gBreakingForce = 0.0f;
}
public void deacelerate() {
gBreakingForce = maxBreakingForce;
gEngineForce = 0.0f;
}
public void updateCamera(LookAtCamera camera) {
Transform chassisWorldTrans = new Transform();
carChassis.getMotionState().getWorldTransform(chassisWorldTrans);
Transform characterWorldTrans = chassisWorldTrans;
Vector3f up = new Vector3f();
characterWorldTrans.basis.getRow(1, up);
Vector3f backward = new Vector3f();
characterWorldTrans.basis.getRow(2, backward);
backward.scale(-1);
up.normalize();
backward.normalize();
camera.lookAtVector.set(characterWorldTrans.origin);
Vector3f cameraPosition = new Vector3f(camera.lookAtVector.x,camera.lookAtVector.y,camera.lookAtVector.z);
up.scale(4);
cameraPosition.add(up);
backward.scale(8);
cameraPosition.add(backward);
// System.out.println("lookat" + camera.lookAtVector);
// System.out.println("position " + cameraPosition + " angle " + cameraPosition.angle(camera.lookAtVector));
// System.out.println(" " + backward + " " + up);
camera.position.set(cameraPosition);
}
public RigidBody localCreateRigidBody(float mass, Transform startTransform, CollisionShape shape) {
boolean isDynamic = (mass != 0f);
Vector3f localInertia = new Vector3f(0f, 0f, 0f);
if (isDynamic) {
shape.calculateLocalInertia(mass, localInertia);
}
DefaultMotionState myMotionState = new DefaultMotionState(startTransform);
RigidBodyConstructionInfo cInfo = new RigidBodyConstructionInfo(mass, myMotionState, shape, localInertia);
RigidBody body = new RigidBody(cInfo);
dynamicsWorld.addRigidBody(body);
return body;
}
public void printVector(Vector3f origin) {
System.out.println(origin.x + " " + origin.y + " " + origin.z);
}
}
Related
How to access ApplicationAdapter instance for anywhere LibGDX
I have a music playing in ApplicationAdapter. I want to pause and play the music form PlayState. How can i access instance of ApplicationAdapter from anywhere. I tried using GreenBot EventBus but it only works with android. Any help? Thanks in advance. Music is playing in below class. package com.brentaureli.game; import com.badlogic.gdx.ApplicationAdapter; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.audio.Music; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.brentaureli.game.states.GameStateManager; import com.brentaureli.game.states.MenuState; public class FlappyDemo extends ApplicationAdapter { public static final int WIDTH = 480; public static final int HEIGHT = 800; public static final String TITLE = "Flappy Bird"; private GameStateManager gsm; private SpriteBatch batch; private Music music; #Override public void create () { batch = new SpriteBatch(); gsm = new GameStateManager(); music = Gdx.audio.newMusic(Gdx.files.internal("music.mp3")); music.setLooping(true); music.setVolume(0.1f); music.play(); Gdx.gl.glClearColor(1, 0, 0, 1); gsm.push(new MenuState(gsm)); } #Override public void render () { Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); gsm.update(Gdx.graphics.getDeltaTime()); gsm.render(batch); } #Override public void dispose() { super.dispose(); music.dispose(); } } I want to pause and play form below class: package com.brentaureli.game.states; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.utils.Array; import com.brentaureli.game.FlappyDemo; import com.brentaureli.game.sprites.Bird; import com.brentaureli.game.sprites.Tube; public class PlayState extends State { private static final int TUBE_SPACING = 125; private static final int TUBE_COUNT = 4; private static final int GROUND_Y_OFFSET = -50; private Bird bird; private Texture bg; private Texture ground; private Vector2 groundPos1, groundPos2; private Array<Tube> tubes; public PlayState(GameStateManager gsm) { super(gsm); bird = new Bird(50, 300); cam.setToOrtho(false, FlappyDemo.WIDTH / 2, FlappyDemo.HEIGHT / 2); bg = new Texture("bg.png"); ground = new Texture("ground.png"); groundPos1 = new Vector2(cam.position.x - cam.viewportWidth / 2, GROUND_Y_OFFSET); groundPos2 = new Vector2((cam.position.x - cam.viewportWidth / 2) + ground.getWidth(), GROUND_Y_OFFSET); tubes = new Array<Tube>(); for(int i = 1; i <= TUBE_COUNT; i++){ tubes.add(new Tube(i * (TUBE_SPACING + Tube.TUBE_WIDTH))); } } #Override protected void handleInput() { if(Gdx.input.justTouched()) bird.jump(); } #Override public void update(float dt) { handleInput(); updateGround(); bird.update(dt); cam.position.x = bird.getPosition().x + 80; for(int i = 0; i < tubes.size; i++){ Tube tube = tubes.get(i); if(cam.position.x - (cam.viewportWidth / 2) > tube.getPosTopTube().x + tube.getTopTube().getWidth()){ tube.reposition(tube.getPosTopTube().x + ((Tube.TUBE_WIDTH + TUBE_SPACING) * TUBE_COUNT)); } if(tube.collides(bird.getBounds())) gsm.set(new MenuState(gsm)); } if(bird.getPosition().y <= ground.getHeight() + GROUND_Y_OFFSET) gsm.set(new MenuState(gsm)); cam.update(); } #Override public void render(SpriteBatch sb) { sb.setProjectionMatrix(cam.combined); sb.begin(); sb.draw(bg, cam.position.x - (cam.viewportWidth / 2), 0); sb.draw(bird.getTexture(), bird.getPosition().x, bird.getPosition().y); for(Tube tube : tubes) { sb.draw(tube.getTopTube(), tube.getPosTopTube().x, tube.getPosTopTube().y); sb.draw(tube.getBottomTube(), tube.getPosBotTube().x, tube.getPosBotTube().y); } sb.draw(ground, groundPos1.x, groundPos1.y); sb.draw(ground, groundPos2.x, groundPos2.y); sb.end(); } #Override public void dispose() { bg.dispose(); bird.dispose(); ground.dispose(); for(Tube tube : tubes) tube.dispose(); System.out.println("Play State Disposed"); } private void updateGround(){ if(cam.position.x - (cam.viewportWidth / 2) > groundPos1.x + ground.getWidth()) groundPos1.add(ground.getWidth() * 2, 0); if(cam.position.x - (cam.viewportWidth / 2) > groundPos2.x + ground.getWidth()) groundPos2.add(ground.getWidth() * 2, 0); } } Full Code: https://github.com/BrentAureli/FlappyDemo
Get ApplicationListener instance anywhere in your game by this. ApplicationListener applicationListener = Gdx.app.getApplicationListener(); Downcast it to FlappyDemo and then you can use data member of your FlappyDemo class. FlappyDemo flappyDemo =(FlappyDemo) applicationListener; flappyDemo.music.play(); Use in a single line ((FlappyDemo)Gdx.app.getApplicationListener()).music;
Lidgdx Java Sprite falling
I was not sure how to title this article. I am making a game that has sprite falling down. I already have triangles falling down in my game. I don't know how to change it where images that I import in the game that allows the image falling. Icicle: package com.udacity.gamedev.icicles; import com.badlogic.gdx.graphics.glutils.ShapeRenderer; import com.badlogic.gdx.math.Vector2; public class Icicle { public static final String TAG = Icicle.class.getName(); Vector2 position; Vector2 velocity; public Icicle(Vector2 position) { this.position = position; this.velocity = new Vector2(); } public void update(float delta) { velocity.mulAdd(Constants.ICICLES_ACCELERATION, delta); position.mulAdd(velocity, delta); } public void render(ShapeRenderer renderer) { renderer.triangle( position.x, position.y, position.x - Constants.ICICLES_WIDTH / 2, position.y + Constants.ICICLES_HEIGHT, position.x + Constants.ICICLES_WIDTH / 2, position.y + Constants.ICICLES_HEIGHT ); } } Icicles: package com.udacity.gamedev.icicles; import com.badlogic.gdx.graphics.glutils.ShapeRenderer; import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.utils.DelayedRemovalArray; import com.badlogic.gdx.utils.viewport.Viewport; import com.udacity.gamedev.icicles.Constants.Difficulty; public class Icicles { public static final String TAG = Icicles.class.getName(); Difficulty difficulty; int iciclesDodged; DelayedRemovalArray<Icicle> icicleList; Viewport viewport; public Icicles(Viewport viewport, Difficulty difficulty) { this.difficulty = difficulty; this.viewport = viewport; init(); } public void init() { icicleList = new DelayedRemovalArray<Icicle>(false, 100); iciclesDodged = 0; } public void update(float delta) { if (MathUtils.random() < delta * difficulty.spawnRate) { Vector2 newIciclePosition = new Vector2( MathUtils.random() * viewport.getWorldWidth(), viewport.getWorldHeight() ); Icicle newIcicle = new Icicle(newIciclePosition); icicleList.add(newIcicle); } for (Icicle icicle : icicleList) { icicle.update(delta); } icicleList.begin(); for (int i = 0; i < icicleList.size; i++) { if (icicleList.get(i).position.y < -Constants.ICICLES_HEIGHT) { iciclesDodged += 1; icicleList.removeIndex(i); } } icicleList.end(); } public void render(ShapeRenderer renderer) { renderer.setColor(Constants.ICICLE_COLOR); for (Icicle icicle : icicleList) { icicle.render(renderer); } } } Constant: package com.udacity.gamedev.icicles; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.math.Vector2; public static final float ICICLES_HEIGHT = 1.0f; public static final float ICICLES_WIDTH = 0.5f; public static final Vector2 ICICLES_ACCELERATION = new Vector2(0,-5.0f); public static final Color ICICLE_COLOR = Color.WHITE;
Paintbrush stroke in JavaFX
I'm trying to write a painting application in JavaFX. I want a brush resembling a real paintbrush, but I'm not sure how to start the algorithm. The code below shows my current paintbrush stroke, although it's a useful stroke, it's not really a paintbrush: import javafx.application.Application; import javafx.scene.Group; import javafx.scene.Scene; import javafx.scene.canvas.Canvas; import javafx.scene.canvas.GraphicsContext; import javafx.scene.input.MouseEvent; import javafx.scene.paint.Color; import javafx.scene.shape.StrokeLineCap; import javafx.scene.shape.StrokeLineJoin; import javafx.stage.Stage; import static javafx.scene.input.MouseEvent.*; public class BrushTester extends Application { private static final Color color = Color.CHOCOLATE; private static final double START_OPACITY = 0.3; private static final double OPACITY_MODIFIER = 0.002; private double currentOpacity = START_OPACITY; private double strokeWidth = 15; public static void main(String[] args) { Application.launch(BrushTester.class); } #Override public void start(Stage primaryStage) throws Exception { Canvas canvas = new Canvas(600d, 600d); GraphicsContext gc = canvas.getGraphicsContext2D(); canvas.addEventHandler(MOUSE_DRAGGED, e -> BrushTester.this.handleMouseDragged(gc, e)); canvas.addEventHandler(MOUSE_PRESSED, e -> handleMousePressed(gc, e)); canvas.addEventHandler(MOUSE_RELEASED, e -> handleMouseReleased(gc, e)); Group root = new Group(); root.getChildren().add(canvas); primaryStage.setScene(new Scene(root, Color.DARKGRAY)); primaryStage.show(); } private void configureGraphicsContext(GraphicsContext gc) { gc.setStroke(new Color(color.getRed(), color.getGreen(), color.getBlue(), currentOpacity)); gc.setLineCap(StrokeLineCap.ROUND); gc.setLineJoin(StrokeLineJoin.ROUND); gc.setLineWidth(strokeWidth); } public void handleMousePressed(GraphicsContext gc, MouseEvent e) { configureGraphicsContext(gc); gc.beginPath(); gc.moveTo(e.getX(), e.getY()); gc.stroke(); } public void handleMouseReleased(GraphicsContext gc, MouseEvent e) { currentOpacity = START_OPACITY; gc.closePath(); } public void handleMouseDragged(GraphicsContext gc, MouseEvent e) { currentOpacity = Math.max(0, currentOpacity - OPACITY_MODIFIER); configureGraphicsContext(gc); gc.lineTo(e.getX(), e.getY()); gc.stroke(); } } Anyone with some tips on how to get closer to the real thing?
It all depends on what you're trying to achieve. Personally I would use an AnimationTimer a customizable Brush (i. e. an Image) instead of a stroke, so you can specify size and hardness a line drawing algorithm (like Bresenham) to connect the previous mouse location with the current one to get a full line between points A quick example with a simple drawing algorithm: import java.util.Random; import javafx.animation.AnimationTimer; import javafx.application.Application; import javafx.geometry.Point2D; import javafx.scene.Node; import javafx.scene.Scene; import javafx.scene.SnapshotParameters; import javafx.scene.canvas.Canvas; import javafx.scene.canvas.GraphicsContext; import javafx.scene.image.Image; import javafx.scene.image.WritableImage; import javafx.scene.input.MouseEvent; import javafx.scene.layout.BorderPane; import javafx.scene.layout.Pane; import javafx.scene.paint.Color; import javafx.scene.paint.CycleMethod; import javafx.scene.paint.RadialGradient; import javafx.scene.paint.Stop; import javafx.scene.shape.Circle; import javafx.stage.Stage; public class Main extends Application { private static double SCENE_WIDTH = 1280; private static double SCENE_HEIGHT = 720; static Random random = new Random(); Canvas canvas; GraphicsContext graphicsContext; AnimationTimer loop; Point2D mouseLocation = new Point2D( 0, 0); boolean mousePressed = false; Point2D prevMouseLocation = new Point2D( 0, 0); Scene scene; Image brush = createBrush( 30.0, Color.CHOCOLATE); double brushWidthHalf = brush.getWidth() / 2.0; double brushHeightHalf = brush.getHeight() / 2.0; #Override public void start(Stage primaryStage) { BorderPane root = new BorderPane(); canvas = new Canvas( SCENE_WIDTH, SCENE_HEIGHT); graphicsContext = canvas.getGraphicsContext2D(); Pane layerPane = new Pane(); layerPane.getChildren().addAll(canvas); root.setCenter(layerPane); scene = new Scene(root, SCENE_WIDTH, SCENE_HEIGHT); primaryStage.setScene(scene); primaryStage.show(); addListeners(); startAnimation(); } private void startAnimation() { loop = new AnimationTimer() { #Override public void handle(long now) { if( mousePressed) { // try this // graphicsContext.drawImage( brush, mouseLocation.getX() - brushWidthHalf, mouseLocation.getY() - brushHeightHalf); // then this bresenhamLine( prevMouseLocation.getX(), prevMouseLocation.getY(), mouseLocation.getX(), mouseLocation.getY()); } prevMouseLocation = new Point2D( mouseLocation.getX(), mouseLocation.getY()); } }; loop.start(); } // https://de.wikipedia.org/wiki/Bresenham-Algorithmus private void bresenhamLine(double x0, double y0, double x1, double y1) { double dx = Math.abs(x1-x0), sx = x0<x1 ? 1. : -1.; double dy = -Math.abs(y1-y0), sy = y0<y1 ? 1. : -1.; double err = dx+dy, e2; /* error value e_xy */ while( true){ graphicsContext.drawImage( brush, x0 - brushWidthHalf, y0 - brushHeightHalf); if (x0==x1 && y0==y1) break; e2 = 2.*err; if (e2 > dy) { err += dy; x0 += sx; } /* e_xy+e_x > 0 */ if (e2 < dx) { err += dx; y0 += sy; } /* e_xy+e_y < 0 */ } } private void addListeners() { scene.addEventFilter(MouseEvent.ANY, e -> { mouseLocation = new Point2D(e.getX(), e.getY()); mousePressed = e.isPrimaryButtonDown(); }); } public static Image createImage(Node node) { WritableImage wi; SnapshotParameters parameters = new SnapshotParameters(); parameters.setFill(Color.TRANSPARENT); int imageWidth = (int) node.getBoundsInLocal().getWidth(); int imageHeight = (int) node.getBoundsInLocal().getHeight(); wi = new WritableImage(imageWidth, imageHeight); node.snapshot(parameters, wi); return wi; } public static Image createBrush( double radius, Color color) { // create gradient image with given color Circle brush = new Circle(radius); RadialGradient gradient1 = new RadialGradient(0, 0, 0, 0, radius, false, CycleMethod.NO_CYCLE, new Stop(0, color.deriveColor(1, 1, 1, 0.3)), new Stop(1, color.deriveColor(1, 1, 1, 0))); brush.setFill(gradient1); // create image return createImage(brush); } public static void main(String[] args) { launch(args); } } Of course you can extend this with e. g. multiple layers JavaFX's blend modes on layer and graphicscontext level to simulate force I'd use a paint delay (eg 200 ms) and a buffer for the mouse locations and let the opacity depend on whether the mouse is still pressed or not smooth the lines by using bezier curves ... Example with Brush variations when you start painting: import java.util.Random; import javafx.animation.AnimationTimer; import javafx.application.Application; import javafx.geometry.Point2D; import javafx.scene.Node; import javafx.scene.Scene; import javafx.scene.SnapshotParameters; import javafx.scene.canvas.Canvas; import javafx.scene.canvas.GraphicsContext; import javafx.scene.image.Image; import javafx.scene.image.WritableImage; import javafx.scene.input.MouseEvent; import javafx.scene.layout.BorderPane; import javafx.scene.layout.Pane; import javafx.scene.paint.Color; import javafx.scene.paint.CycleMethod; import javafx.scene.paint.RadialGradient; import javafx.scene.paint.Stop; import javafx.scene.shape.Circle; import javafx.stage.Stage; public class Main extends Application { private static double SCENE_WIDTH = 1280; private static double SCENE_HEIGHT = 720; static Random random = new Random(); Canvas canvas; GraphicsContext graphicsContext; AnimationTimer loop; Point2D mouseLocation = new Point2D( 0, 0); boolean mousePressed = false; Point2D prevMouseLocation = new Point2D( 0, 0); Scene scene; double brushMaxSize = 30; Image brush = createBrush( brushMaxSize, Color.CHOCOLATE); double brushWidthHalf = brush.getWidth() / 2.0; double brushHeightHalf = brush.getHeight() / 2.0; double pressure = 0; double pressureDelay = 0.04; private Image[] brushVariations = new Image[256]; #Override public void start(Stage primaryStage) { BorderPane root = new BorderPane(); canvas = new Canvas( SCENE_WIDTH, SCENE_HEIGHT); for( int i=0; i < brushVariations.length; i++) { double size = (brushMaxSize - 1) / (double) brushVariations.length * (double) i + 1; brushVariations[i] = createBrush( size, Color.CHOCOLATE); } graphicsContext = canvas.getGraphicsContext2D(); Pane layerPane = new Pane(); layerPane.getChildren().addAll(canvas); root.setCenter(layerPane); scene = new Scene(root, SCENE_WIDTH, SCENE_HEIGHT); primaryStage.setScene(scene); primaryStage.show(); addListeners(); startAnimation(); } private void startAnimation() { loop = new AnimationTimer() { #Override public void handle(long now) { if( mousePressed) { // try this // graphicsContext.drawImage( brush, mouseLocation.getX() - brushWidthHalf, mouseLocation.getY() - brushHeightHalf); // then this bresenhamLine( prevMouseLocation.getX(), prevMouseLocation.getY(), mouseLocation.getX(), mouseLocation.getY()); pressure += pressureDelay; if( pressure > 1) { pressure = 1; } } else { pressure = 0; } prevMouseLocation = new Point2D( mouseLocation.getX(), mouseLocation.getY()); } }; loop.start(); } // https://de.wikipedia.org/wiki/Bresenham-Algorithmus private void bresenhamLine(double x0, double y0, double x1, double y1) { double dx = Math.abs(x1-x0), sx = x0<x1 ? 1. : -1.; double dy = -Math.abs(y1-y0), sy = y0<y1 ? 1. : -1.; double err = dx+dy, e2; /* error value e_xy */ while( true){ int variation = (int) (pressure * (brushVariations.length - 1)); Image brushVariation = brushVariations[ variation ]; graphicsContext.setGlobalAlpha(pressure); graphicsContext.drawImage( brushVariation, x0 - brushWidthHalf, y0 - brushHeightHalf); if (x0==x1 && y0==y1) break; e2 = 2.*err; if (e2 > dy) { err += dy; x0 += sx; } /* e_xy+e_x > 0 */ if (e2 < dx) { err += dx; y0 += sy; } /* e_xy+e_y < 0 */ } } private void addListeners() { scene.addEventFilter(MouseEvent.ANY, e -> { mouseLocation = new Point2D(e.getX(), e.getY()); mousePressed = e.isPrimaryButtonDown(); }); } public static Image createImage(Node node) { WritableImage wi; SnapshotParameters parameters = new SnapshotParameters(); parameters.setFill(Color.TRANSPARENT); int imageWidth = (int) node.getBoundsInLocal().getWidth(); int imageHeight = (int) node.getBoundsInLocal().getHeight(); wi = new WritableImage(imageWidth, imageHeight); node.snapshot(parameters, wi); return wi; } public static Image createBrush( double radius, Color color) { // create gradient image with given color Circle brush = new Circle(radius); RadialGradient gradient1 = new RadialGradient(0, 0, 0, 0, radius, false, CycleMethod.NO_CYCLE, new Stop(0, color.deriveColor(1, 1, 1, 0.3)), new Stop(1, color.deriveColor(1, 1, 1, 0))); brush.setFill(gradient1); // create image return createImage(brush); } public static void main(String[] args) { launch(args); } } Example with variation for limiting the brush length import javafx.animation.AnimationTimer; import javafx.application.Application; import javafx.geometry.Point2D; import javafx.scene.Node; import javafx.scene.Scene; import javafx.scene.SnapshotParameters; import javafx.scene.canvas.Canvas; import javafx.scene.canvas.GraphicsContext; import javafx.scene.control.ColorPicker; import javafx.scene.image.Image; import javafx.scene.image.WritableImage; import javafx.scene.input.MouseEvent; import javafx.scene.layout.BorderPane; import javafx.scene.layout.Pane; import javafx.scene.paint.Color; import javafx.scene.paint.CycleMethod; import javafx.scene.paint.RadialGradient; import javafx.scene.paint.Stop; import javafx.scene.shape.Circle; import javafx.stage.Stage; public class Main extends Application { private static double SCENE_WIDTH = 1280; private static double SCENE_HEIGHT = 720; Canvas canvas; GraphicsContext graphicsContext; AnimationTimer loop; Point2D mouseLocation = new Point2D(0, 0); boolean mousePressed = false; Point2D prevMouseLocation = new Point2D(0, 0); Scene scene; double brushMaxSize = 30; double pressure = 0; double pressureDelay = 0.04; double pressureDirection = 1; double strokeTimeMax = 1; double strokeTime = 0; double strokeTimeDelay = 0.07; private Image[] brushVariations = new Image[256]; ColorPicker colorPicker = new ColorPicker(); #Override public void start(Stage primaryStage) { BorderPane root = new BorderPane(); canvas = new Canvas(SCENE_WIDTH, SCENE_HEIGHT); graphicsContext = canvas.getGraphicsContext2D(); graphicsContext.setFill(Color.WHITE); graphicsContext.fillRect(0, 0, SCENE_WIDTH, SCENE_HEIGHT); Pane layerPane = new Pane(); layerPane.getChildren().addAll(canvas); colorPicker.setValue(Color.CHOCOLATE); colorPicker.setOnAction(e -> { createBrushVariations(); }); root.setCenter(layerPane); root.setTop(colorPicker); scene = new Scene(root, SCENE_WIDTH, SCENE_HEIGHT, Color.WHITE); primaryStage.setScene(scene); primaryStage.show(); createBrushVariations(); addListeners(); startAnimation(); } private void createBrushVariations() { for (int i = 0; i < brushVariations.length; i++) { double size = (brushMaxSize - 1) / (double) brushVariations.length * (double) i + 1; brushVariations[i] = createBrush(size, colorPicker.getValue()); } } private void startAnimation() { loop = new AnimationTimer() { #Override public void handle(long now) { if (mousePressed) { // try this // graphicsContext.drawImage( brush, mouseLocation.getX() - // brushWidthHalf, mouseLocation.getY() - brushHeightHalf); // then this bresenhamLine(prevMouseLocation.getX(), prevMouseLocation.getY(), mouseLocation.getX(), mouseLocation.getY()); // increasing or decreasing strokeTime += strokeTimeDelay * pressureDirection; // invert direction if (strokeTime > strokeTimeMax) { pressureDirection = -1; } // while still if (strokeTime > 0) { pressure += pressureDelay * pressureDirection; // clamp value of pressure to be [0,1] if (pressure > 1) { pressure = 1; } else if (pressure < 0) { pressure = 0; } } else { pressure = 0; } } else { pressure = 0; pressureDirection = 1; strokeTime = 0; } prevMouseLocation = new Point2D(mouseLocation.getX(), mouseLocation.getY()); } }; loop.start(); } // https://de.wikipedia.org/wiki/Bresenham-Algorithmus private void bresenhamLine(double x0, double y0, double x1, double y1) { double dx = Math.abs(x1 - x0), sx = x0 < x1 ? 1. : -1.; double dy = -Math.abs(y1 - y0), sy = y0 < y1 ? 1. : -1.; double err = dx + dy, e2; /* error value e_xy */ while (true) { int variation = (int) (pressure * (brushVariations.length - 1)); Image brushVariation = brushVariations[variation]; graphicsContext.setGlobalAlpha(pressure); graphicsContext.drawImage(brushVariation, x0 - brushVariation.getWidth() / 2.0, y0 - brushVariation.getHeight() / 2.0); if (x0 == x1 && y0 == y1) break; e2 = 2. * err; if (e2 > dy) { err += dy; x0 += sx; } /* e_xy+e_x > 0 */ if (e2 < dx) { err += dx; y0 += sy; } /* e_xy+e_y < 0 */ } } private void addListeners() { canvas.addEventFilter(MouseEvent.ANY, e -> { mouseLocation = new Point2D(e.getX(), e.getY()); mousePressed = e.isPrimaryButtonDown(); }); } public static Image createImage(Node node) { WritableImage wi; SnapshotParameters parameters = new SnapshotParameters(); parameters.setFill(Color.TRANSPARENT); int imageWidth = (int) node.getBoundsInLocal().getWidth(); int imageHeight = (int) node.getBoundsInLocal().getHeight(); wi = new WritableImage(imageWidth, imageHeight); node.snapshot(parameters, wi); return wi; } public static Image createBrush(double radius, Color color) { // create gradient image with given color Circle brush = new Circle(radius); RadialGradient gradient1 = new RadialGradient(0, 0, 0, 0, radius, false, CycleMethod.NO_CYCLE, new Stop(0, color.deriveColor(1, 1, 1, 0.3)), new Stop(1, color.deriveColor(1, 1, 1, 0))); brush.setFill(gradient1); // create image return createImage(brush); } public static void main(String[] args) { launch(args); } } This is how it looks like: or using different colors, I added a color picker in the last example:
Wrong Color DirectMediaPlayer VLCj and Libgdx
I use Libgdx and VLCj to play video, but the color is wrong (the left side on the image is ok). I use DirectMediaPlayer to catch frame data from the memory, create texture and draw on the screen. My code: import java.awt.GraphicsEnvironment; import java.awt.image.BufferedImage; import java.awt.image.DataBufferInt; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.IntBuffer; import uk.co.caprica.vlcj.binding.LibVlc; import uk.co.caprica.vlcj.player.MediaPlayerFactory; import uk.co.caprica.vlcj.player.direct.BufferFormat; import uk.co.caprica.vlcj.player.direct.BufferFormatCallback; import uk.co.caprica.vlcj.player.direct.DirectMediaPlayer; import uk.co.caprica.vlcj.player.direct.RenderCallbackAdapter; import uk.co.caprica.vlcj.player.direct.format.RV32BufferFormat; import uk.co.caprica.vlcj.runtime.RuntimeUtil; import uk.co.caprica.vlcj.runtime.x.LibXUtil; import com.badlogic.gdx.ApplicationListener; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.GL10; import com.badlogic.gdx.graphics.OrthographicCamera; import com.badlogic.gdx.graphics.Pixmap; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.BitmapFont; import com.badlogic.gdx.graphics.g2d.Gdx2DPixmap; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.utils.GdxRuntimeException; import com.sun.jna.Native; import com.sun.jna.NativeLibrary; public class MyGdxGame implements ApplicationListener { private OrthographicCamera camera; private Texture texture; private BitmapFont font; private SpriteBatch batch; float w = 800; float h = 600; private BufferedImage image; private MediaPlayerFactory factory; private DirectMediaPlayer mediaPlayer; private Pixmap pixmap; #Override public void create() { w = Gdx.graphics.getWidth(); h = Gdx.graphics.getHeight(); camera = new OrthographicCamera(); camera.setToOrtho(false, w, h); camera.update(); font = new BitmapFont(); batch = new SpriteBatch(); LibXUtil.initialise(); NativeLibrary.addSearchPath(RuntimeUtil.getLibVlcLibraryName(), "C:\\Users\\Dima\\Desktop\\vlc-2.1.0_64\\"); Native.loadLibrary(RuntimeUtil.getLibVlcLibraryName(), LibVlc.class); image = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration().createCompatibleImage((int) w, (int) h); image.setAccelerationPriority(1.0f); String[] args = { "--no-video-title-show", "--verbose=3" }; String media = "C:\\video512.mp4"; factory = new MediaPlayerFactory(args); mediaPlayer = factory.newDirectMediaPlayer(new TestBufferFormatCallback(), new TestRenderCallback()); mediaPlayer.playMedia(media); System.out.println(LibVlc.INSTANCE.libvlc_get_version()); } #Override public void dispose() { Gdx.app.exit(); } #Override public void render() { Gdx.gl.glClearColor(1, 1, 1, 1); Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT); batch.begin(); if (pixmap != null) { texture = new Texture(pixmap); batch.draw(texture, 0, 0, 800, 600); } font.draw(batch, "FPS: " + Gdx.graphics.getFramesPerSecond(), 10, 20); batch.end(); } private final class TestRenderCallback extends RenderCallbackAdapter { public TestRenderCallback() { super(((DataBufferInt) image.getRaster().getDataBuffer()).getData()); } #Override public void onDisplay(DirectMediaPlayer mediaPlayer, int[] data) { ByteBuffer byteBuffer = ByteBuffer.allocateDirect(data.length * 4).order(ByteOrder.nativeOrder()); IntBuffer intBuffer = byteBuffer.asIntBuffer(); intBuffer.put(data); try { long[] nativeData = new long[] { 0, 800, 600, Gdx2DPixmap.GDX2D_FORMAT_RGBA8888 }; Gdx2DPixmap pixmapData = new Gdx2DPixmap(byteBuffer, nativeData); pixmap = new Pixmap(pixmapData); } catch (Exception e) { pixmap = null; throw new GdxRuntimeException("Couldn't load pixmap from image data", e); } } } private final class TestBufferFormatCallback implements BufferFormatCallback { #Override public BufferFormat getBufferFormat(int sourceWidth, int sourceHeight) { return new RV32BufferFormat((int) w, (int) h); } } #Override public void resize(int width, int height) { } #Override public void pause() { } #Override public void resume() { } } If you know others ways to draw video in java, let me know. Solved! Method getBufferFormat in TestBufferFormatCallback class was not correct. Right variant: #Override public BufferFormat getBufferFormat(int sourceWidth, int sourceHeight) { sourceWidth = 800; sourceHeight = 600; System.out.println("Got VideoFormat: " + sourceWidth + "x" + sourceHeight); BufferFormat format = new BufferFormat("RGBA", sourceWidth, sourceHeight, new int[] { sourceWidth * 4 }, new int[] { sourceHeight }); return format; }
libgdx - How to draw some pixel
I am trying to alter a pixmap and render it, but modified pixels are not shown on screen. I'm not sure if a Pixmap is the best way to do it. Can anyone explain to me where my errors are in the code below ? thanks package com.me.mygdxgame; import com.badlogic.gdx.ApplicationListener; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.GL10; import com.badlogic.gdx.graphics.OrthographicCamera; import com.badlogic.gdx.graphics.Pixmap; import com.badlogic.gdx.graphics.Pixmap.Format; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.Texture.TextureFilter; import com.badlogic.gdx.graphics.g2d.Sprite; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.utils.Array; public class MyGdxGame implements ApplicationListener { private OrthographicCamera camera; private SpriteBatch batch; private Pixmap _pixmap; private int _width; private int _height; private Texture _pixmapTexture; private Sprite _pixmapSprite; private int _x = 0; private int _y = 0; #Override public void create() { float w = Gdx.graphics.getWidth(); float h = Gdx.graphics.getHeight(); camera = new OrthographicCamera(1, h/w); batch = new SpriteBatch(); _width = (int)Math.round(w); _height = (int)Math.round(h); _pixmap = new Pixmap( _width, _height, Format.RGBA8888 ); _pixmap.setColor(Color.RED); _pixmap.fillRectangle(0, 0, _width, _height); _pixmapTexture = new Texture(_pixmap, Format.RGB888, false); } #Override public void dispose() { batch.dispose(); _pixmap.dispose(); _pixmapTexture.dispose(); } #Override public void render() { updatePixMap(); Gdx.gl.glClearColor(1, 1, 1, 1); Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT); batch.setProjectionMatrix(camera.combined); batch.begin(); batch.draw(_pixmapTexture, -_width/2, -_height/2); batch.end(); } private void updatePixMap() { _x += 1; if (_x >= _width) { _x = 0; } _y += 1; if (_y >= _height / 2) { return; } _pixmap = new Pixmap( _width, _height, Format.RGBA8888 ); _pixmap.setColor(Color.CYAN); _pixmap.drawPixel(_x, _y); _pixmapTexture = new Texture(_pixmap, Format.RGB888, false); } #Override public void resize(int width, int height) { } #Override public void pause() { } #Override public void resume() { } }
You are creating a new pixmap every loop and you don't draw the complete texture in your view. import com.badlogic.gdx.ApplicationListener; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.GL10; import com.badlogic.gdx.graphics.OrthographicCamera; import com.badlogic.gdx.graphics.Pixmap; import com.badlogic.gdx.graphics.Pixmap.Format; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.math.MathUtils; public class MyGdxGame implements ApplicationListener { private OrthographicCamera camera; private SpriteBatch batch; private Pixmap _pixmap; private Texture _pixmapTexture; private int _x = 0; private int _y = 0; private float _w; private float _h; private int _width; private int _height; #Override public void create() { _w = Gdx.graphics.getWidth(); _h = Gdx.graphics.getHeight(); _width = MathUtils.round(_w); _height = MathUtils.round(_h); camera = new OrthographicCamera(1f, _h / _w); camera.setToOrtho(false); batch = new SpriteBatch(); _pixmap = new Pixmap(_width, _height, Format.RGBA8888); _pixmap.setColor(Color.RED); _pixmap.fillRectangle(0, 0, _width, _height); _pixmapTexture = new Texture(_pixmap, Format.RGB888, false); } #Override public void dispose() { batch.dispose(); _pixmap.dispose(); _pixmapTexture.dispose(); } #Override public void pause() { } #Override public void render() { updatePixMap(); Gdx.gl.glClearColor(1, 1, 1, 1); Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT); batch.setProjectionMatrix(camera.combined); batch.begin(); batch.draw(_pixmapTexture, 1f / 2f, _h / _w / 2f); batch.end(); } #Override public void resize(final int width, final int height) { } #Override public void resume() { } private void updatePixMap() { _x += 1; if (_x >= _width) _x = 0; _y += 1; if (_y >= _height / 2) return; _pixmap.setColor(Color.CYAN); _pixmap.drawPixel(_x, _y); _pixmapTexture = new Texture(_pixmap, Format.RGB888, false); } } But this is very slow, so why do you want to do it?