LWJGL/OpenGL -- Not drawing basic quad - lwjgl

I have looked everywhere, and I can't seem to get OpenGL to draw a simple quad.
The window shows up fine with the correct color background, but OpenGL just won't draw the box.
I am using OpenGL 4.4.0 - Build 20.19.15.4463
The window size is 1920x1080
This is the code I currently have:
in Main.java:
public void init(){
if(glfwInit() != true){
System.err.println("GLFW failed to initialize");
}
glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);
//TODO change name.
window = glfwCreateWindow(width, height, "GameName", NULL, NULL);
if(window == NULL){
System.err.println("Window failed to be created");
}
GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
glfwSetWindowPos(window, 100, 100);
glfwMakeContextCurrent(window);
glfwShowWindow(window);
GL.createCapabilities();
glClearColor(0.0f, 0.5f, 1.0f, 1.0f);
glEnable(GL_DEPTH_TEST);
//set up projection matrix; allows us to draw.
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, width, height, 0, 1, -1);
glMatrixMode(GL_MODELVIEW);
testBox = new EntityBox(3, Color.RED);//just to test right now
System.out.println("OpenGL: "+ glGetString(GL_VERSION));
}
public void update(){
glfwPollEvents();
}
public void render(){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glfwSwapBuffers(window);
testBox.draw();
}
in EntityBox:
public void draw(){
glColor3f(1.0f, 0.0f, 0.0f);
glBegin(GL_QUADS);
glVertex2f(0,0);
glVertex2f(0,100);
glVertex2f(100,0);
glVertex2f(100,100);
glEnd();
}

I fixed it:
glClear needs to be
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
don't know why, because i was tole depth_buffer is used if you want 3d.
and
glfwSwapBuffers(window);
needs to be called after drawing.

Related

How to scale down Texture in libgdx to fit smaller screens?

My app provides two buttons in a table row. Each image has a width of 300 pixel (source). The app shows all parts of both buttons if I provide an initial window width which is greater than 600. Even resizing the window to a smaller size works smoothly. Both buttons are shown fully and they get scaled down if needed when resizing the window. The buttons are cut off once I provide an initial window size which is smaller than 600 pixel. How can I show the whole buttons on small screens by default?
Screenshots:
My code looks like this:
public class LevelChooserState extends GameState {
private Stage stage;
private Texture bgTexture;
private Pixmap bgPixmap;
private Viewport viewportStage;
private Container<Table> container;
private Table table;
public LevelChooserState(final GameStateController gsc) {
super(gsc);
Gdx.app.log(TAG, "Setup Level Chooser State.");
// Setup Background Color
bgPixmap = new Pixmap(1, 1, Pixmap.Format.RGB565);
bgPixmap.setColor(Color.WHITE);
bgPixmap.fill();
bgTexture = new Texture(bgPixmap);
TextureRegionDrawable textureRegionDrawableBg = new TextureRegionDrawable(new TextureRegion(bgTexture));
// Setup viewports
viewportStage = new ExtendViewport(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
viewportStage.setScreenBounds(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
// Setup stage
stage = new Stage(viewportStage);
Gdx.input.setInputProcessor(stage);
// Setup font
int Help_Guides = 12;
int row_height = Gdx.graphics.getWidth() / 12;
FreeTypeFontGenerator generator = new FreeTypeFontGenerator(Gdx.files.internal("fonts/PatrickHand-Regular.ttf"));
FreeTypeFontGenerator.FreeTypeFontParameter parameter = new FreeTypeFontGenerator.FreeTypeFontParameter();
parameter.size = 30;
parameter.borderWidth = 1;
parameter.color = Color.BLACK;
BitmapFont myFont = generator.generateFont(parameter);
generator.dispose();
// Setup background pictures
TextureAtlas textureAtlas = new TextureAtlas("atlas/onoff.atlas");
TextureRegion backgroundTR1 = textureAtlas.findRegion("onoff_off");
TextureRegion backgroundTR2 = textureAtlas.findRegion("onoff_on");
// Setup TextButtons
TextureRegionDrawable up1= new TextureRegionDrawable(backgroundTR1);
TextureRegionDrawable down1= new TextureRegionDrawable(backgroundTR2);
TextureRegionDrawable checked1= new TextureRegionDrawable(backgroundTR2);
String text1 = "Deceptive dance in the poultry house.";
ClickListener clickListner1 = new ClickListener() {
#Override
public void clicked(InputEvent event, float x, float y) {
Gdx.app.log(Constants.TAG, "Button click received.");
gsc.setState(GameStateController.State.PLAY);
}
};
TextButton textButton1 = createTextButton(myFont, text1, up1, down1, checked1, clickListner1);
// ... created some more buttons at this point
// Setup Layout
container = new Container<Table>();
container.setBounds(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
container.setBackground(textureRegionDrawableBg);
container.align(Align.bottomLeft);
table = new Table();
table.setBounds(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
table.setTouchable(Touchable.enabled);
table.setDebug(true);
table.debugAll();
table.setBackground(textureRegionDrawableBg);
table.setFillParent(true);
table.align(Align.top);
// TODO take care of scaling too when setting padding
float padding = 10;
table.row();
table.add(textButton1).expandX().pad(padding);
table.add(textButton2).expandX().pad(padding);
table.row();
table.add(textButton3).expandX().pad(padding);
table.add(textButton4).expandX().pad(padding);
table.row();
container.setActor(table);
stage.addActor(container);
}
private TextButton createTextButton(BitmapFont font, String text, TextureRegionDrawable up, TextureRegionDrawable down, TextureRegionDrawable checked, ClickListener clickListener) {
Label.LabelStyle labelStyle = new Label.LabelStyle();
labelStyle.font = font;
Label label = new Label(text,labelStyle);
label.setWrap(true);
TextButton.TextButtonStyle style = new TextButton.TextButtonStyle();
style.up = up;
style.down = down;
style.checked = checked;
style.font = font;
TextButton button = new TextButton(label.toString(), style);
//button.setSize(50,100);
button.setLabel(label);
button.getLabelCell().pad(20f);
button.getLabel().setAlignment(Align.topLeft);
button.setPosition(0,0);
button.addListener(clickListener);
return button;
}
#Override
public void update(float delta) {
}
#Override
public void render() {
Gdx.gl.glClearColor(1f,1f,1f,1f);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.setProjectionMatrix(camera.combined);
batch.begin();
stage.getViewport().apply();
stage.draw();
stage.act();
batch.end();
}
#Override
public void dispose() {
Gdx.app.log(TAG, "dispose(); Level Chooser");
stage.dispose();
bgPixmap.dispose();
bgTexture.dispose();
}
#Override
public void resize(int w, int h) {
Gdx.app.log(TAG, "resize() LevelChooserState;");
stage.getViewport().update(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), true);
container.setFillParent(true); // makes sure the container will expand on resize
}
}
LibGDX uses real-pixel-to-screen-pixel mapping.
You're using an ExtendViewport to initialize the game, which takes its minimum height and width from the actual window size in Gdx.graphics.getWidth(), Gdx.graphics.getHeight().
This means that the 'fake screen' you have, which you can then resize as much as you want, is actually determined by the size of the window.
I would advise you start with a fixed size for the ExtendViewport - say, 600 width, 400 height - and later you can change this to suit different sizes if necessary.
ExtendViewport with fixed sizes works fantastically well, even when displaying on extremely large screens.
It works smoothly once I calculate and set the desired button manually. Width and height are calculated depending on screen size.
I changed this:
table.add(textButton1).expandX().pad(padding);
to this:
float buttonWidth = Gdx.graphics.getWidth()/2 * 0.9f;
float buttonHeight = buttonWidth * 1.3f;
table.add(textButton1).width(buttonWidth).height(buttonHeight).expandX().pad(padding);

Why camera in stage is not required to be centered in libgdx

How stage camera is able to see full stage view if (0,0) of the camera is located by default at (0,0) of stage. if update method for viewport is not called nor camera position set method is called.
If you look into the Stage Constructor:
public Stage (Viewport viewport, Batch batch) {
if (viewport == null) throw new IllegalArgumentException("viewport cannot be null.");
if (batch == null) throw new IllegalArgumentException("batch cannot be null.");
this.viewport = viewport;
this.batch = batch;
root = new Group();
root.setStage(this);
viewport.update(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), true);
}
We see on the last line viewport.update() with the width, height and true as parameters.
Let's look at this viewport.update() method:
public void update (int screenWidth, int screenHeight, boolean centerCamera) {
apply(centerCamera);
}
Now let's look on the apply() method. We know centerCamera is true:
public void apply (boolean centerCamera) {
HdpiUtils.glViewport(screenX, screenY, screenWidth, screenHeight);
camera.viewportWidth = worldWidth;
camera.viewportHeight = worldHeight;
if (centerCamera) camera.position.set(worldWidth / 2, worldHeight / 2, 0);
camera.update();
}
And here we find the answer: if (centerCamera) camera.position.set(worldWidth / 2, worldHeight / 2, 0);
The stage centered the camera position on her own.

How to make a sprite blink X seconds?

I'm using libGDX and I want to make my main character of my game to blinking x seconds on enemy touch (lose life)
Can someone tell me how can I make sprite to blinding?
Here is my solution, I use it exactly for the same purpose you described (blinking character when he injured).
public class Blinker {
private float BLINK_TIME = 1f;
private int BLINKING_FRAMES = 4;
private boolean isBlinking;
private int blinkFrameCounter;
private float blinkTimer;
public Blinker() {
this.blinkTimer = 0;
this.blinkFrameCounter = 0;
this.isBlinking = false;
}
public boolean shouldBlink(float delta) {
if (isBlinking) {
blinkTimer += delta;
blinkFrameCounter++;
if (blinkTimer < BLINK_TIME) {
if (blinkFrameCounter % BLINKING_FRAMES == 0) {
return true;
}
} else {
blinkTimer = 0;
isBlinking = false;
}
}
return false;
}
public boolean isBlinking() {
return isBlinking;
}
public void setBlinking(boolean isBlinking) {
this.isBlinking = isBlinking;
}
}
Usage:
first init the blinker object;
Blinker blinker= new Blinker();
blinker.setBlinking(true);
and then just add this to your draw() method (I suppose that you have separate method for drawing character, which you call in your screen draw method), before you draw the sprite you want to blink.
if (blinker.shouldBlink(delta))
return;
I recommend looking at something like this.
https://github.com/libgdx/libgdx/wiki/2D-Animation
You use this technique and adjust the frame duration.
walkAnimation = new Animation(0.025f, walkFrames); // #11
When you need to start making the animation blink faster. adjust the frame duration value.
public void setFrameDuration(float frameDuration)
I recommend doing it this way but if you HAVE to tint it w/e.... I guess this works.
private Texture texture;
private TextureRegion region;
private Sprite sprite;
...
texture = new Texture(Gdx.files.internal("image.png"));
region = new TextureRegion(texture, 20, 20, 50, 50);
sprite = new Sprite(texture, 20, 20, 50, 50);
sprite.setPosition(100, 10);
sprite.setColor(0, 0, 1, 1);
...
batch.begin();
batch.setColor(1, 0, 0, 1);
batch.draw(texture, 10, 10);
batch.setColor(0, 1, 0, 1);
batch.draw(region, 50, 10);
sprite.draw(batch);
batch.end();
key thing is Alpha is ignored if blending is disabled.
The previous answer from prgenhard will work, but I don't think that is sufficient enough, if you are using it without care.
You can use TweenEngine to interpolate alpha value with different functions.
It can be really cool.
Those values you can set on sprite's or actor's alpha and easily achieve flashing effect.
You can read more about it here:
http://www.aurelienribon.com/blog/projects/universal-tween-engine/
It should be enough.
And also it can be easily used within Libgdx engine.
Hope this helps.

TextureRegion in ArrayList Won't draw to screen

I'm having some issues drawing TextureRegions with a spriteBatch in LibGDX.
So I have a main class that hosts the game logic.
In the constructor, I have:
atlas = new TextureAtlas(Gdx.files.internal("sheet.txt") );
this.loadTileGFX();
the loadTileGFX() method does this:
roseFrames = new ArrayList<AtlasRegion>();
roseFrames.add(atlas.findRegion("Dirt", 0));
roseFrames.add(atlas.findRegion("Dirt", 1));
roseFrames.add(atlas.findRegion("Dirt", 2));
roseFrames.add(atlas.findRegion("Dirt", 3));
Then I pass the arrayList of AtlasRegions into the object:
///in the main class
rsoe = new RoseSquare(roseFrames, st, col, row, tileWidth);
//in the constructor for the object to draw
this.textureRegions = roseFrames;
Then every render() loop I call:
batch.begin();
rose.draw(batch);
batch.end()
The rose.draw() method looks like this:
public void draw(SpriteBatch batch){
batch.draw(this.textureRegions.get(1), rect.x, rect.y, rect.width, rect.height);
}
But the thing is, this doesn't draw anything to the screen.
BUT HERE'S THE THING.
If I change the code to be:
public void draw(SpriteBatch batch){
batch.draw(new TextureAtlas(Gdx.files.internal("sheet.txt")).findRegion("Dirt", 0)), rect.x, rect.y, rect.width, rect.height);
}
Then it draws correctly.
Can anybody shed some light on what error I might have?
Keep in ming I don't get any errors with the "nothing drawn" code.
Also, I can trace the details of this.textureRegions.get(1), and they all are correct....
Thanks.
If you need to draw an array of something that has textures you can do like this:
batch.begin();
for (Ground ground : groundArray){
batch.draw(ground.getTextureRegion(), ground.x, ground.y);
}
batch.end();
As you see i am drawing the TextureRegion here.
You can check related classes and other information in my answers HERE and HERE
Answering drew's comment:
public TextureRegion customGetTextureRegion(int i){
switch(i){
case 1: return atlas.findRegion("dirt1"); break;
case 2: return atlas.findRegion("dirt2"); break;
case 3: return atlas.findRegion("dirt3"); break;
}
}
I have found a solution to my own problem.
I was also drawing some debug ShapeRenderer stuff.
The issue seemed to be that libGDX didn't like a SpriteBatch and a ShapeRenderer to be "on" at the same time:
//LibGDX Doesn't like this:
spriteBatch.begin();
shapeRenderer.begin(ShapeType.Line);
shapeRenderer.drawRect(x, y, width, height);
shapeRenderer.end();
sprtieBatch.draw(texRegion, x, y, width, height);
spriteBatch.end();
It prefers:
//LibGDX likes this:
shapeRenderer.begin(ShapeType.Line);
shapeRenderer.drawRect(x, y, width, height);
shapeRenderer.end();
spriteBatch.begin();
sprtieBatch.draw(texRegion, x, y, width, height);
spriteBatch.end();
Thanks for your responses everyone.

Libgdx: screen resize and ClickListener (libgdx)

I develope a 2D game and use OrthographicCamera and Viewport to resize virtaul board to real display size. I add images to stage and use ClickListener to detect clicks. It works fine, but when I change resolution it works incorrent(can't detect correct actor, I think the problem with new and original x and y). Is there any way to fix this?
You will need to translate the screen coordinates to world coordinates.
Your camera can do that. You can do both ways, cam.project(...) and cam.unproject(...)
Or if you are already using Actors, don't initialize a camera yourself, but use a Stage. Create a Stage and add the actors to it. The Stage will then do coordinate translation for you.
Once me too suffered from this problem but at end i got the working solution, for drawing anything using SpriteBatch or Stage in libgdx. Using orthogrphic camera we can do this.
first choose one constant resolution which is best for game. Here i have taken 1280*720(landscape).
class ScreenTest implements Screen{
final float appWidth = 1280, screenWidth = Gdx.graphics.getWidth();
final float appHeight = 720, screenHeight = Gdx.graphics.getHeight();
OrthographicCamera camera;
SpriteBatch batch;
Stage stage;
Texture img1;
Image img2;
public ScreenTest(){
camera = new OrthographicCamera();
camera.setToOrtho(false, appWidth, appHeight);
batch = new SpriteBatch();
batch.setProjectionMatrix(camera.combined);
img1 = new Texture("your_image1.png");
img2 = new Image(new Texture("your_image2.png"));
img2.setPosition(0, 0); // drawing from (0,0)
stage = new Stage(new StretchViewport(appWidth, appHeight, camera));
stage.addActor(img2);
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(1, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
batch.draw(img, 0, 0);
batch.end();
stage.act();
stage.act(delta);
stage.draw();
// Also You can get touch input according to your Screen.
if (Gdx.input.isTouched()) {
System.out.println(" X " + Gdx.input.getX() * (appWidth / screenWidth));
System.out.println(" Y " + Gdx.input.getY() * (appHeight / screenHeight));
}
}
//
:
:
//
}
run this code in Any type of resolution it will going to adjust in that resolution without any disturbance.
I just think Stage is easy to use.
If there are some wrong,i consider you should check your code:
public Actor hit(float x, float y)