I'm currently stuck in front of a problem.
I work on Android with API 19 with Eclipse IDE using Java.
I've done an Activity which contains some Layouts. And i've put in one of these layout a custom class which inherits from GLSurfaceView in order to provide a 3D rendering for the user.
But actually i have a problem on a specific device, the "Epson moverio" glasses which works with Android 4.04.
When the softkeyboard pops out, it shows me the GLSurfaceView and also a black square which have the same dimensions as GLSurfaceView and this black square is contiguous with the GLSurfaceView. I don't understand why i have this bug, because it works well on classic devices like samsung tablets and i have another version of the view on which i draw 2D shapes using canvas, and i don't get the black square problem, it seems that kind of problem happens only with openGL rendering context (i'm using openGL 2.0 ES).
it seems that this bug occurs only when the softkeyboard pops on the screen.
I tried to put an invalidate() and a forceLayout function call in onSurfaceChanged and onSizeChanged but it doesn't work.
I point out that the bug only occurs on the "Epson moverio" glasses and i don't understand why.
Is it a good way to build my own class which inherits from GLSurfaceView, and put it into the Activity's layout in order to display 3D or is there another better way to do that kind of feature ?
Here's some snippet of code of my GLSurfaceView class implementation
#Override
public void onDrawFrame(GL10 gl) {
// TODO Auto-generated method stub
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
long time = SystemClock.uptimeMillis() % 10000L;
float angleInDegrees = (360.0f / 10000.0f) * ((int) time);
if (_trolleyContentInfoList != null && _trolleyCaracteristics != null) {
_matrixTools.loadIndentity(MatrixType.MODEL_MATRIX);
drawTrolleyStructure(angleInDegrees);
drawTrolleyShelves(angleInDegrees);
//drawTrolleyWheels(angleInDegrees);
}
}
#Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
// TODO Auto-generated method stub
GLES20.glViewport(0, 0, width, height);
float aspect = (float)width / height;
float fovy = 60.0f;
float near = 0.1f;
float far = 10.0f;
_width = width;
_height = height;
_matrixTools.loadIndentity(MatrixType.PROJECTION_MATRIX);
_matrixTools.perspective(MatrixType.PROJECTION_MATRIX, fovy, aspect, near, far);
this.forceLayout();
}
#Override
public void onSizeChanged(int w, int h, int oldw, int oldh) {
this.forceLayout();
}
#Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
GLES20.glClearColor(0.8f, 0.8f, 0.8f, 0.0f);
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
_matrixTools.loadIndentity(MatrixType.VIEW_MATRIX);
_matrixTools.lookAt(MatrixType.VIEW_MATRIX, 0.0f, 0.0f, -2.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
_matrixTools.loadIndentity(MatrixType.MODEL_MATRIX);
_cubeDrawer = new CubeDrawer();
_cubeDrawer.initialize();
}
And, finally, here's how my custom class inherits from GLSurfaceView
public class Trolley3DView extends GLSurfaceView implements GLSurfaceView.Renderer, ITrolleyPreviewView{
}
Edit : Okay after a test i've seen that the black square dissapear after typing something into a TextView in the Activity. Must i understand that i should invalidate the Activity in order to force it to refresh when the softkeyboard pops out ?
Okay, i finnaly found the reason of the bug. You have to set the color of the View on which you display openGL content, and the black square will magically disapear.
Related
I want to have three separate rectangles that would fill up with gradient. Depending on the value X the gradient would be placed differently. For example if value X = 75 the gradient would be 75% green and 25% red. I wanted to know if there is any library or a method that would allow me to do this in java (android studio).
To implement this, you could use LinearGradient for the gradient and then create a custom view with methods allowing you to change the layout of the gradient.
public class GradientView extends View {
Paint paint;
LinearGradient gradient;
int[] colors = [Color.RED, Color.GREEN];
public GradientView(Context context, int gradientHeight) {
super(context);
paint = new Paint();
setGradientHeight(gradientHeight);
}
#Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
paint.setShader(colorGradient);
canvas.drawPaint(paint);
}
public void setGradientHeight(int height){
colorGradient = new LinearGradient(0, 0, 0, height * 0.01 * super.getHeight(), colors, null, Shader.TileMode.MIRROR);
paint.setShader(colorGradient);
invalidate();
}
}
Haven't tested the code, but it should certainly work something like this.
I'm currently working on a libgdx game and before I give it final touches I wanted to actually hear something from experienced users, that has been bothering me for a few days already.
If I want to support as many as possible devices, essentially I will be designing graphics for the biggest possible res ,which is then going to be scaled if needed, for smaller screens, right? How do I go about developing for a resolution that is even bigger than my laptop's(the 2015/16 gen phones). My laptop has a resolution of 1920x1080px and the S7 Samsung has 2k+ width.
Thank you!
I think what you are looking for is Viewports. You have to decide which strategy fits best your needs. For example a FitViewport always keeps the aspect ratio you define, which might lead to black bars on some devices.
When I personally develop with libgdx I place and size all objects relative to the screen width and height. This includes images, fonts, buttons, etc. This gives me a pretty consistent result across all devices because most devices today have a ratio 16:9 or something close to it. For developing an image larger than your screen size what's wrong with just using photoshop to create the image of the specified size?
Better you choose the screen with as 1280 and screen height as 800 and also use the fill viewPort . So you will be able to render your game in almost all the screens without the issue of stretching.
Viewport is the method which provided by the libgdx to solve this multi screen compatible issue . here i will post some sample code which you can use for the reference.
public class myGame extends ApplicationAdapter {
public OrthographicCamera camera;
public Viewport viewPort;
private SpriteBatch batch;
private BitmapFont myScoreFont;
private Texture texture;
public myGAme() {
}
#Override
public void create() {
myScoreFont = new BitmapFont(Gdx.files.internal(Constants.PATH_TO_MY_SCORE_FONT), true);
batch = new SpriteBatch();
float w = Gdx.graphics.getWidth();
float h = Gdx.graphics.getHeight();
texture = new Texture(Gdx.files.internal(Constants.PATH_TO_LEFT_BAR));
camera = new OrthographicCamera();
camera.position.set(0, 0, 0);
camera.update();
camera.setToOrtho(false, Constants.APP_WIDTH, Constants.APP_HEIGHT);
// Here is the viewport is setting up with the camera and the screen size
viewPort = new FillViewport(1280, 800, camera);
}
#Override
public void dispose() {
batch.dispose();
}
#Override
public void render() {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL30.GL_COLOR_BUFFER_BIT);
float deltaTime = Gdx.graphics.getDeltaTime();
batch.setProjectionMatrix(camera.combined);
batch.begin();
batch.draw(myScorefont,"Score",0,0);
batch.end();
}
#Override
public void resize(int width, int height) {
// the game area will be resized as per the screen size of the device
viewPort.update(width, height);
}
#Override
public void pause() {
}
#Override
public void resume() {
}
}
Im working on my 3D Game with LibGdx.
After looking some other Threads and posts with some realy good tutorials I get the first shader working. My Problem now is to get a Cel/Outline/Toon Shader working.
Therefore I found also a tutorial and a project but they havnt worked.
After reading some posts how to solve this shading Problem (with rendering the Object twice,...) I tried this method but got some sideeffects.
Actually I got as result a darfred rendering Scene.
My Question is now, If my Models just need some other Material or why I get these results.
I wrote a cel shader based on the KBAL tutorial that results in renderings like the one above. I've been meaning to write up something on it since the library has changed a lot since then. It seems like you got stuck on the depth shader, which is one of the parts from the original tutorial that needed the most updating.
Besides compatibility updates, I removed one render pass by modifying the uber shader that comes with LibGDX to perform the discretization in the KBAL tutorial's toonify() function during the initial rendering of geometry rather than in a post pass. Aside from that it follows the same pattern.
The code below is a bare bones implementation of my cel shader code. The class is derived extends AbstractScreen which implements some base functionality for LibGDX's Screen interface. Read more about Screen's here and see the CelTutorialScreen source within a full project context here.
package com.hh.ghoststory.screen;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.assets.AssetManager;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.PerspectiveCamera;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.graphics.g3d.Environment;
import com.badlogic.gdx.graphics.g3d.Model;
import com.badlogic.gdx.graphics.g3d.ModelBatch;
import com.badlogic.gdx.graphics.g3d.ModelInstance;
import com.badlogic.gdx.graphics.g3d.environment.DirectionalLight;
import com.badlogic.gdx.graphics.glutils.FrameBuffer;
import com.badlogic.gdx.graphics.glutils.ShaderProgram;
import com.badlogic.gdx.math.Matrix4;
import com.badlogic.gdx.utils.Array;
import com.hh.ghoststory.GhostStory;
import com.hh.ghoststory.render.shaders.CelDepthShaderProvider;
import com.hh.ghoststory.render.shaders.CelLineShaderProgram;
public class CelTutorialScreen extends AbstractScreen {
private PerspectiveCamera camera = new PerspectiveCamera(67, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
private AssetManager assetManager = new AssetManager();
private Array<ModelInstance> instances = new Array<ModelInstance>();
private FrameBuffer fbo;
private TextureRegion textureRegion;
private ShaderProgram lineShader = new CelLineShaderProgram();
private SpriteBatch spriteBatch = new SpriteBatch();
private ModelBatch modelBatch = new ModelBatch(Gdx.files.classpath("com/badlogic/gdx/graphics/g3d/shaders/default.vertex.glsl").readString(), Gdx.files.internal("shaders/cel.main.fragment.glsl").readString());
private ModelBatch depthBatch = new ModelBatch(new CelDepthShaderProvider());
private Environment environment = new Environment();
public CelTutorialScreen(GhostStory game) {
super(game);
Gdx.gl.glClearColor(1.0f, 0.0f, 1.0f, 0.0f);
Gdx.gl.glClear(GL20.GL_DEPTH_BUFFER_BIT | GL20.GL_COLOR_BUFFER_BIT);
// setup camera
camera.position.set(5, 5, 5);
camera.lookAt(0, 0, 0);
camera.near = 1;
camera.far = 1000;
camera.update();
// add a light
environment.add(new DirectionalLight().set(0.8f, 0.8f, 1.8f, -1f, -0.8f, 0.2f));
// load our model
assetManager.load("models/spider.g3dj", Model.class);
loading = true;
}
#Override
public void render(float delta) {
if (loading && assetManager.update())
doneLoading();
camera.update();
Gdx.gl.glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
Gdx.gl.glClear(GL20.GL_DEPTH_BUFFER_BIT | GL20.GL_COLOR_BUFFER_BIT);
// render depth map to fbo
captureDepth();
// draw the scene
renderScene();
// put fbo texture in a TextureRegion and flip it
prepTextureRegion();
// draw the cel outlines
drawOutlines();
}
/*
* Draws the cel outlines using the CelLineShaderProgram
*/
protected void drawOutlines() {
spriteBatch.setShader(lineShader);
lineShader.setUniformf("u_size", Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
spriteBatch.begin();
spriteBatch.draw(textureRegion, 0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
spriteBatch.end();
spriteBatch.setShader(null);
}
/*
* Stores fbo texture in a TextureRegion and flips it vertically.
*/
protected void prepTextureRegion() {
textureRegion = new TextureRegion(fbo.getColorBufferTexture());
textureRegion.flip(false, true);
}
/*
* Draws the depth pass to an fbo, using a ModelBatch created with CelDepthShaderProvider()
*/
protected void captureDepth() {
fbo.begin();
Gdx.gl.glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
Gdx.gl.glClear(GL20.GL_DEPTH_BUFFER_BIT | GL20.GL_COLOR_BUFFER_BIT);
depthBatch.begin(camera);
depthBatch.render(instances);
depthBatch.end();
fbo.end();
}
/*
* Renders the scene.
*/
protected void renderScene() {
Gdx.gl.glClear(GL20.GL_DEPTH_BUFFER_BIT | GL20.GL_COLOR_BUFFER_BIT);
modelBatch.begin(camera);
modelBatch.render(instances, environment);
modelBatch.end();
}
#Override
protected void doneLoading() {
loading = false;
instances.add(new ModelInstance(assetManager.get("models/spider.g3dj", Model.class)));
}
/*
* Set camera width and height, SpriteBatch projection matrix, and reinit the FBOs
*/
#Override
public void resize(int width, int height) {
camera.position.set(camera.position);
camera.viewportWidth = width;
camera.viewportHeight = height;
camera.update();
if (fbo != null) fbo.dispose();
fbo = new FrameBuffer(Pixmap.Format.RGBA8888, Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), true);
spriteBatch.setProjectionMatrix(new Matrix4().setToOrtho2D(0, 0, width, height));
}
#Override
public void dispose() {
assetManager.dispose();
modelBatch.dispose();
depthBatch.dispose();
spriteBatch.dispose();
fbo.dispose();
lineShader.dispose();
}
}
The render performs 3 passes to create the end product.
The first is contained in the captureDepth() function.
protected void captureDepth() {
fbo.begin();
Gdx.gl.glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
Gdx.gl.glClear(GL20.GL_DEPTH_BUFFER_BIT | GL20.GL_COLOR_BUFFER_BIT);
depthBatch.begin(camera);
depthBatch.render(instances);
depthBatch.end();
fbo.end();
}
A framebuffer is started, glClear is called and then the depthBatch ModelBatch() renders the model instances (only one in this case) before the framebuffer is ended.
The depthBatch is a ModelBatch that uses a CelDepthShaderProvider, which provides a CelDepthShader. CellDepthShaderProvider is a small class that extends BaseShaderProvider and overrides createShader to return an instance of CelDepthShader, which registers and sets u_near and u_far uniforms as well as sets up the use of the cel depth vertex and fragment GLSL shaders.
I'm guessing the GLSL files are where you're running into issues. The vertex shader I linked to is the same as the KBAL vertex shader with the exception of line 125, which removed some artifacts on the cel edges:
v_depth = (pos.z + u_near) / (u_far - u_near);
The fragment shader is very similar to the one in the KBAL tutorial, but is actually copied from LibGDX's built in depth fragment shader. It's quite possible that the current LigGDX DepthShader could be used instead of my CelDepthShader, but I haven't had time to look into this.
After the first pass, the packed depth map has been captured by the FBO. The second pass is ready to be run and will draw the scene with LibGDXs' default vertex shader and a slightly modified version of its fragment shader.
The changes from the default fragment shader are in lines 140-150 where the specular value is discretized before being added to gl_FragColor:
if (specIntensity > 0.6)
specFactor = 1.0;
else if (specIntensity > 0.3)
specFactor = 0.5;
else
specFactor = 0.1;
specular *= specFactor;
And 173-182 where the overall gl_FragColor is discretized:
float intensity = max(gl_FragColor.r, max(gl_FragColor.g, gl_FragColor.b));
float factor;
if (intensity > 0.8)
factor = 1.0;
else if (intensity > 0.5)
factor = 0.8;
else if (intensity > 0.25)
factor = 0.3;
else
factor = 0.1;
And that's it for the main cel pass.
Next in render() the prepTextureRegion() function is called. This just puts the depth texture captured to our fbo into a texture region and flips it vertically before using it to draw the cel outlines in the final pass.
The final pass is performed in drawOutlines() and makes use of a SpriteBatch since we're drawing a 2d texture instead of geometry. The call to spriteBatch.setShader(lineshader) sets the SpriteBatch to use an instance of CelLineShaderProgram, another class that extends ShaderProgram. It sets a u_size uniform and uses cel.line.vertex.glsl and cel.line.fragment.glsl.
This shader program runs the Laplace filter. The vertex shader is copied from the KBAL edge shader and updated to work with newer versions of LibGDX, it passes the sampled coordinate of the depth map as well as its top, bottom, left and right neighboring texels to the fragment shader as varyings.
The fragment shader uses an updated method of unpacking the depth values based on code from the getShadowness() function here as recommended by Xoppa.
There are some improvements to this process that could be made. For one, I haven't implemented the super sampling in the original tutorial.
Also, it's not really noticeable in this still image, but once you have a controllable camera in the scene, or geometry moving around, you'll notice the per pixel lighting looks a little weird, especially with limited polygons in your geometry. There is a per-pixel lighting fragment shader in the LibGDX shadow system tests that could be used as a base to implement this with cel shading. The shadow systems might even be a good base to create a multi-pass rendering system for cel shading. And there is undoubtedly code that could be removed from the modified base LibGDX shaders I've used, as well as other optimizations and cleanup.
Hope this helps you or anyone else looking for info on multipass cel shading.
I have tried to make a ellipse object in libgdx. Sorry if i can't describe properly but im a newbie in java.
My code looks like:
public class GameScreen implements Screen{
MyGame game;
OrthographicCamera camera;
SpriteBatch batch;
...
Ellipse playBounds;
public GameScreen(MyGame game) {
this.game = game;
camera = new OrthographicCamera();
camera.setToOrtho(false, 1080, 1920);
batch = new SpriteBatch();
state = GAME_READY;
touchPoint = new Vector3();
pauseBounds = new com.badlogic.gdx.math.Rectangle(1080-128,1920-128,128,128);
playBounds= new Ellipse()
}
...
public void render(float delta) {
Gdx.gl.glClearColor(1F, 1F, 1F, 1F);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.update();
generalupdate();
batch.setProjectionMatrix(camera.combined);
batch.begin();
batch.draw(Assets.sprite_bg, 0, 0);
switch (state){
case GAME_READY:{
batch.draw(Assets.sprite_startScreen, 0, 0);
batch.draw(Assets.sprite_playButton,218,800,644,225);
break;
}
Basically it draws background, a welcome screen and a button(with "play" on it)
So here i made a touch detection.
if (Gdx.input.justTouched()) {
camera.unproject(touchPoint.set(Gdx.input.getX(), Gdx.input.getY(), 0));
if (state==GAME_READY);
if (playBounds.contains(touchPoint.x, touchPoint.y)) {
state=GAME_RUNNING;
Drawing works fine but the problem is when i touch the button it doesnt work instead if i touch near it game starts as it should
Alright, ignoring the several errors in the code which I will just assume were made here instead of the actual code, I believe the problem could be that you are not setting the values in the Ellipse. By this I mean the width, height, x, and y.
An nice way to do this would be to use the constructor:
Ellipse(float x, float y, float width, float height)
instead of just :
Ellipse()
That way you can set the values right away. Refer to this website for more info in Ellipses for LibGDX.
If that doesn't solve your problem you may have to post a little more of the relevant parts of your code.
I have been looking for 10 hours (literally) and I'm done, I need to ask. Thing is I'm learning How use LibGdx to program Java games. I'm doing a Horizontal Space Ship Game. So, my worst problem here is that I do not know how do scroll (I think draw will explain better). I want to draw a huge background (Space) and make my OrthographicCamera move right like with my SpaceShip, so it will create a Scroll effect with the Space Background. No enemies and nothing but the ship on the screen.
I'm trying this:
public void moveCamera(float x,float y){
cam.position.set(x, y, 0);
}
Then I use that method in my WorldRender render() method:
public void render(float delta){
ship.Move(delta);
moveCamera(ship.getPosition().x,ship.getPosition().y);
cam.update();
System.out.println(""+cam.position);
spriteBatch.begin();
drawBackground();
drawShip();
spriteBatch.end();
}
I actually move the camera position (I can see that thanks to the println), but It isn't moving in the game, so SpaceShip just disappears by the edge of the window.
I also tried this before spriteBatch.end()
spriteBatch.setProjectionMatrix(camera.combined);
but when I do that windows only shows a black screen, no ship, no nothing.
As I said, I'm desperate, I see lot of examples (scroll with mouse, paralexscrolling etc) but all are to advanced or just nothing to do with my code.
This is how I draw stuff. Background and ship are textures inside WorldRender. I draw background image very wide, so my intention is do some scrolling over as I said. That's the code
private void loadTextures(){
shipTexture=new Texture(Gdx.files.internal("nave.png"));
background=new Texture(Gdx.files.internal("fondo.jpg"));
}
public void drawShip(){
spriteBatch.draw(shipTexture,ship.getPosition().x*ppuX,ship.getPosition().y*ppuY, ship.WIDTH*ppuX,ship.HEIGHT*ppuY);
}
public void drawBackground(){
spriteBatch.draw(background, -10*ppuX,0*ppuY, Gdx.graphics.getWidth()*10,Gdx.graphics.getHeight());
}
Here you can download the code if someone want to help in hardcore mode
My code (not working)
I FINALLY SOLVED IT!
That's the code I used in a class name WorldRenderer, which have methods that are called within GameScreen for render, resize etc
public WorldRenderer(World world) {
// TODO Auto-generated constructor stub
this.world=world;
this.ship=world.getShip();
this.cam = new OrthographicCamera(CAMERA_WIDTH,CAMERA_HEIGHT);
this.cam.setToOrtho(false,CAMERA_WIDTH,CAMERA_HEIGHT);
this.cam.position.set(ship.getPosition().x,CAMERA_HEIGHT/2,0);
this.cam.update();//actualizamos la camara
spriteBatch=new SpriteBatch();
loadTextures();
}
private void loadTextures(){
shipTexture=new Texture(Gdx.files.internal("nave.png"));
background=new Texture(Gdx.files.internal("fondo.jpg"));
}
public void drawShip(){
spriteBatch.draw(shipTexture,ship.getPosition().x,ship.getPosition().y,10,10);
}
public void drawBackground(){
spriteBatch.draw(background, 0,0, 500,50);
}
public void render(float delta){
ship.Move(delta);
moveCamera(ship.getPosition().x);
spriteBatch.setProjectionMatrix(cam.combined);
spriteBatch.begin();
drawBackground();
drawShip();
spriteBatch.end();
}
public void moveCemara(float x){
cam.position.set(x+20,cam.position.y, 0);
cam.update();
}
Inside the Ship I have this method which I call within render in WorldRenderer to move It
public void Move(float delta){
if(Gdx.input.isKeyPressed(Keys.LEFT)) this.position.x -=velocity *delta;
if(Gdx.input.isKeyPressed(Keys.RIGHT)) this.position.x +=velocity *delta;
if(Gdx.input.isKeyPressed(Keys.UP)) this.position.y +=velocity *delta;
if(Gdx.input.isKeyPressed(Keys.DOWN)) this.position.y -=velocity *delta;
}
Also I want to thanks very much to the people who helped me. I'm marking first answer as the good one, but, mix both was what gave me the real solution.
I leave here some tutorials I followed which are pretty good for noobs
That's a good everything-from-scratching-tutorial
LiGdxForNoobs
A simple platform game
platformGame
A very simple game
bucketGame
I can't tell if this is your only mistake, but this is ONE mistake. If this is what you say you were doing:
spriteBatch.begin();
drawBackground();
drawShip();
spriteBatch.setProjectionMatrix(camera.combined);
spriteBatch.end();
You wont see anything. When setProjectionMatrix is called inside a begin()/end() block. the current batch is flushed to the gpu. So, you are actually not drawing anything with the camera matrix. You should do this instead:
spriteBatch.setProjectionMatrix(camera.combined);
spriteBatch.begin();
drawBackground();
drawShip();
spriteBatch.end();
EDIT:
If you don't call that line, spriteBatch uses its own default camera (which wont notice your camera.update() modifications, so that's not what you want).
You should now pay more attention to the coordinates you are using. I'm not quite sure you really need the ppu conversion thing. To begin with, define everything in imaginary world coordinates, note that you'll see some stretching in your world.
public void drawShip(){
spriteBatch.draw(shipTexture,ship.getPosition().x,ship.getPosition().y, 10, 10);
}//your ship is 10 units wide and tall!
public void drawBackground(){
spriteBatch.draw(background, -10,0, 500, 100);
} //your background is 500 units wide, and 100 units tall
//camera setup
camera = new OrthographicCamera(50, 50);
//your camera will print to screen 50 units of your world
If you get to see a stretched world, try to understand how it's working (if you can't see anything, there is something wrong somewhere).
EDIT 2
I took a look at your code. First remove ppu's, as it obscures your code. You were setting your cam position to the ship.postion, while drawing at ship.position * ppu. Also your background was way too big (that's why you see it pixelated). You should see something reasonable with this. (someday you'll have to initialize your camera in another way to deal with stretching, but forget it until you understand how all works).
this.cam = new OrthographicCamera(CAMERA_WIDTH,CAMERA_HEIGHT);
public void drawShip(){
spriteBatch.draw(shipTexture, ship.getPosition().x ,ship.getPosition().y, 10, 10);
}
public void drawBackground(){
spriteBatch.draw(background, -CAMERA_WIDTH/2, -CAMERA_HEIGHT/2, 100, 100); //let bg begin where camera starts. (0,0)
}
public void render(float delta){
ship.Move(delta);
moverCamara(ship.getPosition().x, ship.getPosition().y);
spriteBatch.setProjectionMatrix(cam.combined);
spriteBatch.begin();
drawBackground();
drawShip();
spriteBatch.end();
}
Its not clear how your drawing? I'm not sure if your doing this approach correctly.. Can you provide details of your background and ship? Can you provide details on you background image, is it a huge image that your scrolling around or is it a repeated image you want to repeat as you scroll?
--EDIT--
ok i think i have an idea what might be up. I would normally apply the camera to the current context.
Place the following in your resize
public void resize(int width, int height) {
cam = new OrthographicCamera(width, height);
cam.translate(width / 2, height / 2, 0);
}
Place the following in the start of your render()
cam.position.set(posX,posY,0);
cam.update();
cam.apply(Gdx.gl10);
Gdx.gl.glClearColor(0,0,0,1);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); // #14
This will make you have a clear screen with the origin set at the bottom left of the window. You should then draw your background first
spriteBatch.setProjectionMatrix(cam.combined);
spriteBatch.begin();
spriteBatch.draw(background,0,0,sizeX,sizeY);
spriteBatch.end()
see how that looks as you move your camera position posX and posY. Then add your ship to the mix
-- MORE EDITS ---
you can then calculate the posX and posY as
posX = defaultOffsetX+shipX
and so on..
Anyhow hope this helps
I'm still only learning myself so this might not be the best method.. but it seems to work.
I've edited your code. Have a look at the following:
public class WorldRenderer {
private World world;
private Ship ship;
private Texture shipTexture,background;
private SpriteBatch spriteBatch;
private OrthographicCamera cam;
float screenSizeX = 100;
float screenSizeY = 100;
float shipSizeX = 10;
float shipSizeY = 10;
public void setSize (int w, int h) {
cam = new OrthographicCamera(screenSizeX,screenSizeY);
}
public WorldRenderer(World world) {
this.world=world;
this.ship=world.getShip();
spriteBatch=new SpriteBatch();
loadTextures();
}
private void loadTextures(){
shipTexture=new Texture(Gdx.files.internal("nave.png"));
background=new Texture(Gdx.files.internal("fondo2.jpg"));
}
public void drawShip(){
spriteBatch.draw(shipTexture, ship.getPosition().x,ship.getPosition().y, shipSizeX,shipSizeY);
}
public void drawBackground(){
spriteBatch.draw(background, 0,0);
}
public void render(float delta){
ship.Move(delta);
moverCamara(ship.getPosition().x,ship.getPosition().y);
spriteBatch.setProjectionMatrix(cam.combined);
spriteBatch.begin();
drawBackground();
drawShip();
spriteBatch.end();
}
public void moverCamara(float x,float y){
cam.position.set(x, y, 0);
cam.update();
}
}
This way, your ship is always in the middle of the screen and the background moves. Hope this helps.