LibGDX depth test error - java

I am doing some basic code in LibGDX and want to render a grid of green spheres, but the depth testing which I set to LEQUAL has an error. The error is it seems to render them back to front like GEQUAL.
Here's a screenshot - https://www.imageupload.co.uk/image/5ot2.
Here's the code -
MyGdxGame.java
package com.mygdx.game;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.PerspectiveCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.VertexAttributes.Usage;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g3d.Environment;
import com.badlogic.gdx.graphics.g3d.Material;
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.attributes.ColorAttribute;
import com.badlogic.gdx.graphics.g3d.environment.DirectionalLight;
import com.badlogic.gdx.graphics.g3d.utils.CameraInputController;
import com.badlogic.gdx.graphics.g3d.utils.DefaultTextureBinder;
import com.badlogic.gdx.graphics.g3d.utils.ModelBuilder;
import com.badlogic.gdx.graphics.g3d.utils.RenderContext;
import com.badlogic.gdx.utils.Array;
public class MyGdxGame extends ApplicationAdapter {
Environment env;
PerspectiveCamera camera;
CameraInputController camController;
ModelBatch modelBatch;
Array<ModelInstance> instances;
CustomShader shader;
#Override
public void create () {
env = new Environment();
env.set(new ColorAttribute(ColorAttribute.AmbientLight,
0.5f, 0.5f, 0.5f, 1.0f));
env.add(new DirectionalLight().set(0.7f, 0.7f, 0.7f,
1.0f, 1.0f, 1.0f));
camera = new PerspectiveCamera(60.0f, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
camera.position.set(0.0f, 5.0f, 0.0f);
camera.lookAt(10.0f, 5.0f, 10.0f);
camera.near = 0.0f;
camera.far = 300.0f;
camera.update();
camController = new CameraInputController(camera);
Gdx.input.setInputProcessor(camController);
modelBatch = new ModelBatch();
instances = new Array<ModelInstance>();
ModelBuilder mb = new ModelBuilder();
for(float x = 0.0f; x < 100.0f; x += 10.0f) {
for(float z = 0.0f; z < 100.0f; z += 10.0f) {
Model model = mb.createSphere(5.0f, 5.0f, 5.0f, 20, 20,
new Material(),
Usage.Position | Usage.Normal | Usage.TextureCoordinates);
ModelInstance instance = new ModelInstance(model);
instance.transform.setTranslation(x, 0.0f, z);
instances.add(instance);
}
}
shader = new CustomShader();
shader.init();
}
#Override
public void dispose () {
instances.clear();
}
#Override
public void render () {
camController.update();
Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
modelBatch.begin(camera);
for(ModelInstance instance : instances) {
modelBatch.render(instance, shader);
}
modelBatch.end();
}
}
CustomShader.java
package com.mygdx.game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Camera;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.g3d.Renderable;
import com.badlogic.gdx.graphics.g3d.Shader;
import com.badlogic.gdx.graphics.g3d.utils.RenderContext;
import com.badlogic.gdx.graphics.glutils.ShaderProgram;
import com.badlogic.gdx.utils.GdxRuntimeException;
public class CustomShader implements Shader {
ShaderProgram program;
int u_worldTrans, u_projViewTrans;
#Override
public void dispose() {
program.dispose();
}
#Override
public void init() {
String vert = Gdx.files.internal("shaders/custom.vertex.glsl").readString();
String frag = Gdx.files.internal("shaders/custom.fragment.glsl").readString();
program = new ShaderProgram(vert, frag);
if(!program.isCompiled()) {
throw new GdxRuntimeException(program.getLog());
}
// Cache uniform positions
u_worldTrans = program.getUniformLocation("u_worldTrans");
u_projViewTrans = program.getUniformLocation("u_projViewTrans");
}
#Override
public int compareTo(Shader other) {
return 0;
}
#Override
public boolean canRender(Renderable instance) {
return true;
}
#Override
public void begin(Camera camera, RenderContext context) {
program.begin();
program.setUniformMatrix(u_projViewTrans, camera.combined);
context.setDepthTest(GL20.GL_LEQUAL);//not working/displaying GEQUAL instead?
context.setCullFace(GL20.GL_BACK);
}
#Override
public void render(Renderable renderable) {
program.setUniformMatrix(u_worldTrans, renderable.worldTransform);
renderable.mesh.render(program,
renderable.primitiveType,
renderable.meshPartOffset,
renderable.meshPartSize);
}
#Override
public void end() {
program.end();
}
}
custom.vertex.glsl
uniform mat4 u_worldTrans;
uniform mat4 u_projViewTrans;
attribute vec3 a_position;
attribute vec3 a_normal;
attribute vec2 a_texCoord0;
varying vec2 v_texCoord0;
void main() {
v_texCoord0 = a_texCoord0;
gl_Position = u_projViewTrans * u_worldTrans * vec4(a_position, 1.0);
}
custom.fragment.glsl
#ifdef GL_ES
precision mediump float;
#endif
varying vec2 v_texCoord0;
void main() {
//gl_FragColor = vec4(v_texCoord0, 0.0f, 1.0f);
gl_FragColor = vec4(0.0f, (0.5f*v_texCoord0.x)/v_texCoord0.y, 0.0f, 1.0f);
}

Related

How can an object get destroyed through the camera sight? [duplicate]

This question already has an answer here:
How to make player get destroyed through camera?
(1 answer)
Closed 5 years ago.
I've been having some trouble making the player get destroyed through the camera. In my application, I made the camera follow the player(the ball). But the camera can only follow the ball upwards. So what I want to accomplish is, when the player(the ball) reaches the bottom of the interface(the screen) it gets destroyed. After it gets destroyed it would be good, if a new activity(new screen) pops up, that says "Game over". Thanks a lot for the great support. Please take a look at the interface of the application.
package com.luca.tuninga;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.World;
import com.badlogic.gdx.physics.box2d.Box2DDebugRenderer;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef;
import com.badlogic.gdx.physics.box2d.CircleShape;
import com.badlogic.gdx.physics.box2d.PolygonShape;
import com.badlogic.gdx.utils.viewport.Viewport;
public class MyGdxGame extends ApplicationAdapter {
public static float APP_FPS = 60f;
public static int V_WIDTH = 480;
public static int V_HEIGHT = 640;
Box2DDebugRenderer b2dr;
World world;
Body ballBody;
OrthographicCamera camera;
float cameraMaxY;
#Override
public void create() {
world = new World(new Vector2(0, -9.8f), false);
b2dr = new Box2DDebugRenderer();
camera = new OrthographicCamera();
camera.setToOrtho(false, V_WIDTH, V_HEIGHT);
cameraMaxY = camera.position.y;
ballBody = createBall();
createWalls();
}
private void update() {
world.step(1f / APP_FPS, 6, 2);
if (Gdx.input.isTouched()) {
ballBody.setLinearVelocity(0, MathUtils.clamp(ballBody.getLinearVelocity().y, 0, 3));
ballBody.applyForceToCenter(new Vector2(0, 650f), false);
}
if (ballBody.getPosition().y * 32 > cameraMaxY) {
camera.translate(0, (ballBody.getPosition().y * 32) - cameraMaxY);
camera.update();
cameraMaxY = camera.position.y;
}
}
#Override
public void render() {
Gdx.gl.glClearColor(.25f, .25f, .25f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
update();
b2dr.render(world, camera.combined.cpy().scl(32f));
}
#Override
public void dispose() {
super.dispose();
world.dispose();
}
private Body createBall() {
Body body;
BodyDef def = new BodyDef();
def.type = BodyDef.BodyType.DynamicBody;
def.fixedRotation = true;
def.position.set(camera.position.x/ 32 + .5f, camera.position.y/ 32);
def.position.set(camera.position.x, camera.position.y);
def.gravityScale = 3;
CircleShape shape = new CircleShape();
shape.setRadius(0.5f);
body = world.createBody(def);
body.createFixture(shape, 1.0f);
return body;
}
private void createWalls() {
Body body;
BodyDef def = new BodyDef();
def.type = BodyDef.BodyType.StaticBody;
def.fixedRotation = true;
PolygonShape shape = new PolygonShape();
shape.setAsBox(1, 200 / 32);
for(int i = 0; i < 20 ; i++) {
def.position.set(1.01f, i * (200 / 32));
body = world.createBody(def);
body.createFixture(shape, 1.0f);
def.position.set(V_WIDTH / 32 - 1, i * (200 / 32));
body = world.createBody(def);
body.createFixture(shape, 1.0f);
}
}
}
#Override
public void render() {
Gdx.gl.glClearColor(.25f, .25f, .25f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
if (ballBody.getPosition().y < camera.position.y){
destroyBall();
} else if (ballBody.getPosition().y > camera.position.y + 300){
camera.position.set(ballBody.getPosition().y - 300);
}
update();
b2dr.render(world, camera.combined.cpy().scl(32f));
}
I hope this works. You can write destroyBall() method yourself.

Java LibGDX Remove Bullet Issue

I am trying to remove created bullets when (bullet.position.y <= 0). But the game gives error. I can not remove created bullets. How can I fix it? I used one texture ( 64 x 64 ) and these are my classes:
Game1 (Main Class)
package com.outlook.anil136.game1;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.math.Vector3;
import java.util.ArrayList;
public class Game1 extends ApplicationAdapter {
private ShapeRenderer shapeRenderer;
private SpriteBatch batch;
private OrthographicCamera camera;
private Texture blueTexture;
private Player player1;
private ArrayList<Bullet> bullets;
private Sprite blueSprite;
#Override
public void create () {
shapeRenderer = new ShapeRenderer();
batch = new SpriteBatch();
camera = new OrthographicCamera();
camera.setToOrtho(false, 480, 800);
blueTexture = new Texture("BlueRectangle.png");
player1 = new Player(blueTexture, new Vector2(240, 600));
bullets = new ArrayList<Bullet>();
blueSprite = new Sprite(blueTexture);
}
#Override
public void render () {
Gdx.gl.glClearColor(0.1f, 0.1f, 0.1f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
shapeRenderer.setProjectionMatrix(camera.combined);
shapeRenderer.begin(ShapeRenderer.ShapeType.Filled);
shapeRenderer.rectLine(0, 401, 480, 401, 2);
shapeRenderer.end();
batch.setProjectionMatrix(camera.combined);
batch.begin();
player1.draw(batch);
for (Bullet bullet : bullets) {
bullet.draw(batch);
bullet.update(Gdx.graphics.getDeltaTime());
if (bullet.position.y <= 0)
bullet.remove(bullets);
}
blueSprite.setPosition(416, 736);
blueSprite.setColor(1, 1, 1, 0.5f);
blueSprite.draw(batch);
batch.end();
player1.update(Gdx.graphics.getDeltaTime());
for (int i = 0; i < 20; i++) {
Vector3 touchPosition = camera.unproject(new Vector3(Gdx.input.getX(i), Gdx.input.getY(i), 0));
if (Gdx.input.isTouched(i) && touchPosition.y >= 401 && touchPosition.y > 64 && !new Rectangle(416, 736, 64, 64).contains(touchPosition.x, touchPosition.y))
player1.touchPosition = touchPosition;
if (Gdx.input.justTouched() && new Rectangle(416, 736, 64, 64).contains(touchPosition.x, touchPosition.y))
bullets.add(new Bullet(blueTexture, new Vector2(player1.position), -player1.speed));
}
if (player1.position.y + 32 > 800)
player1.position.y = 768;
else if (player1.position.y - 32 < 402)
player1.position.y = 434;
}
#Override
public void dispose () {
shapeRenderer.dispose();
batch.dispose();
blueTexture.dispose();
}
}
Player
package com.outlook.anil136.game1;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.math.Vector3;
import java.util.ArrayList;
import javafx.scene.input.KeyCode;
import sun.security.provider.SHA;
public class Game1 extends ApplicationAdapter {
private ShapeRenderer shapeRenderer;
private SpriteBatch batch;
private OrthographicCamera camera;
private Texture blueTexture;
private Player player1;
public static ArrayList<Bullet> bullets;
private Sprite blueSprite;
#Override
public void create () {
shapeRenderer = new ShapeRenderer();
batch = new SpriteBatch();
camera = new OrthographicCamera();
camera.setToOrtho(false, 480, 800);
blueTexture = new Texture("BlueRectangle.png");
player1 = new Player(blueTexture, new Vector2(240, 600));
bullets = new ArrayList<Bullet>();
blueSprite = new Sprite(blueTexture);
}
#Override
public void render () {
Gdx.gl.glClearColor(0.1f, 0.1f, 0.1f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
shapeRenderer.setProjectionMatrix(camera.combined);
shapeRenderer.begin(ShapeRenderer.ShapeType.Filled);
shapeRenderer.rectLine(0, 401, 480, 401, 2);
shapeRenderer.end();
batch.setProjectionMatrix(camera.combined);
batch.begin();
player1.draw(batch);
for (Bullet bullet : bullets) {
bullet.draw(batch);
bullet.update(Gdx.graphics.getDeltaTime());
if (bullet.position.y <= 0)
bullet.remove(bullets);
}
blueSprite.setPosition(416, 736);
blueSprite.setColor(1, 1, 1, 0.5f);
blueSprite.draw(batch);
batch.end();
player1.update(Gdx.graphics.getDeltaTime());
for (int i = 0; i < 20; i++) {
Vector3 touchPosition = camera.unproject(new Vector3(Gdx.input.getX(i), Gdx.input.getY(i), 0));
if (Gdx.input.isTouched(i) && touchPosition.y >= 401 && touchPosition.y > 64 && !new Rectangle(416, 736, 64, 64).contains(touchPosition.x, touchPosition.y))
player1.touchPosition = touchPosition;
if (Gdx.input.justTouched() && new Rectangle(416, 736, 64, 64).contains(touchPosition.x, touchPosition.y))
bullets.add(new Bullet(blueTexture, new Vector2(player1.position), -player1.speed));
}
if (player1.position.y + 32 > 800)
player1.position.y = 768;
else if (player1.position.y - 32 < 402)
player1.position.y = 434;
}
#Override
public void dispose () {
shapeRenderer.dispose();
batch.dispose();
blueTexture.dispose();
}
}
Bullet
package com.outlook.anil136.game1;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Vector2;
import java.util.ArrayList;
public class Bullet {
private Texture texture;
Vector2 position;
private int speed;
public Bullet(Texture texture, Vector2 position, int speed) {
this.texture = texture;
this.position = position;
this.speed = speed;
}
public void draw(SpriteBatch batch) {
batch.draw(texture, position.x - 16, position.y - 16, 32, 32);
}
public void update(float deltaTime) {
position.y += speed;
}
public void remove(ArrayList<Bullet> bullets) {
bullets.remove(this);
}
}
You can't remove elements from list when you are iterating it. To remove elements when iterating you need to mark bullet to remove and after iterating actually remove all marked bullets from the main list.
List<Bullet> bulletsToRemove = new ArrayList<Bullet>();
for (Bullet bullet : bullets) {
bullet.draw(batch);
bullet.update(Gdx.graphics.getDeltaTime());
if (bullet.position.y <= 0)
bulletsToRemove.add(bullet);
}
bullets.removeAll(bulletsToRemove);

OpenGL 3.2 Texture Not Displaying

I'm trying to create a class to speed up the production of textured polygons in my program but the texture is not displaying.
I'm using LWJGL with Slick2D for the texture loading.
This is my TexturedPolygon class:
package zeus.core.geom;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;
import org.lwjgl.util.vector.Vector2f;
import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.opengl.TextureLoader;
import zeus.core.Disposable;
public class TexturedPolygon extends Disposable {
private final List<Float> vertices = new ArrayList<Float>();
private final List<Float> texCoords = new ArrayList<Float>();
private final int VAO, VBO;
private final FloatBuffer vertBuffer;
private final ByteBuffer texBuffer;
private final int GL_DRAWING_MODE;
private final String IMG_FILE;
private final Texture TEXTURE;
public TexturedPolygon(final LinkedHashMap<Vector2f, Vector2f> info, final String IMG_FILE, final int GL_DRAWING_MODE) throws IOException {
this.IMG_FILE = IMG_FILE;
this.GL_DRAWING_MODE = GL_DRAWING_MODE;
this.TEXTURE = TextureLoader.getTexture(".png", new FileInputStream(new File(System.getProperty("user.dir") + "/res/img/", IMG_FILE)));
for(Map.Entry<Vector2f, Vector2f> entry : info.entrySet()) {
vertices.add(entry.getKey().x);
vertices.add(entry.getKey().y);
texCoords.add(entry.getValue().x);
texCoords.add(entry.getValue().y);
}
vertBuffer = BufferUtils.createFloatBuffer(vertices.size());
final float[] vertArray = new float[vertices.size()];
int i = 0;
for(final float f : vertices) {
vertArray[i++] = f;
}
vertBuffer.put(vertArray);
vertBuffer.flip();
VAO = GL30.glGenVertexArrays();
GL30.glBindVertexArray(VAO);
VBO = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, VBO);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, vertBuffer, GL15.GL_STATIC_DRAW);
GL20.glEnableVertexAttribArray(0);
GL20.glVertexAttribPointer(0, 2, GL11.GL_FLOAT, false, 0, 0);
GL30.glBindVertexArray(VAO);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, TEXTURE.getTextureID());
texBuffer = BufferUtils.createByteBuffer(TEXTURE.getTextureData().length);
texBuffer.put(TEXTURE.getTextureData());
texBuffer.flip();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, TEXTURE.getTextureID());
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, texBuffer, GL15.GL_STATIC_DRAW);
GL20.glVertexAttribPointer(1, 4, GL11.GL_FLOAT, false, 0, 0);
GL20.glEnableVertexAttribArray(1);
}
public void draw() {
GL30.glBindVertexArray(VAO);
GL11.glDrawArrays(GL_DRAWING_MODE, 0, vertices.size());
GL30.glBindVertexArray(0);
}
public void update(final int delta) {
}
#Override
public void dispose() {
GL20.glDisableVertexAttribArray(0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GL15.glDeleteBuffers(VBO);
GL30.glBindVertexArray(0);
GL30.glDeleteVertexArrays(VAO);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, TEXTURE.getTextureID());
}
public int getVAO() {
return VAO;
}
public int getVBO() {
return VBO;
}
public int getDrawingMode() {
return GL_DRAWING_MODE;
}
public FloatBuffer getVertBuffer() {
return vertBuffer;
}
public ByteBuffer getTextureBuffer() {
return texBuffer;
}
public List<Float> getVertices() {
return vertices;
}
public List<Float> getTexCoords() {
return texCoords;
}
public String getImageFilename() {
return IMG_FILE;
}
}
This is my main class:
package tests;
import java.util.LinkedHashMap;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL20;
import org.lwjgl.util.vector.Vector2f;
import zeus.core.Window;
import zeus.core.geom.TexturedPolygon;
import zeus.core.opengl.Shader;
import zeus.core.opengl.ShaderProgram;
public class WindowTest {
public static void main(String[] args) throws Exception {
final Window win = new Window(800, 600, "Window Test");
win.create();
Shader vertexShader = new Shader("drawing_test_vertex", GL20.GL_VERTEX_SHADER);
Shader fragmentShader = new Shader("drawing_test_fragment", GL20.GL_FRAGMENT_SHADER);
ShaderProgram program = new ShaderProgram();
vertexShader.compile();
fragmentShader.compile();
LinkedHashMap<Vector2f, Vector2f> info = new LinkedHashMap<Vector2f, Vector2f>();
info.put(new Vector2f(0f, 0f), new Vector2f(0f, 0f));
info.put(new Vector2f(1f, 0f), new Vector2f(1f, 0f));
info.put(new Vector2f(1f, 1f), new Vector2f(1f, 1f));
info.put(new Vector2f(1f, 1f), new Vector2f(1f, 1f));
info.put(new Vector2f(0f, 1f), new Vector2f(0f, 1f));
info.put(new Vector2f(0f, 0f), new Vector2f(0f, 0f));
TexturedPolygon p = new TexturedPolygon(info, "test.png", GL11.GL_TRIANGLES);
program.addShader(vertexShader);
program.addShader(fragmentShader);
program.link();
program.use();
while(!win.isCloseRequested()) {
win.clear();
p.update(1);
p.draw();
win.update(120);
}
p.dispose();
vertexShader.dispose();
fragmentShader.dispose();
program.dispose();
win.dispose();
}
}
And these are my shader files:
Vertex:
#version 410
layout(location=0) vec3 pos;
layout(location=1) vec2 tex;
out smooth vec2 Tex;
void main() {
gl_Position = vec4(pos, 1.0f);
Tex = tex;
}
Fragment:
#version 410
layout(location=0) vec2 Tex;
uniform sampler2D textureDiffuse;
out vec4 color;
void main() {
color = texture(textureDiffuse, Tex);
}
I have no idea what is causing the problem.
This is what is currently displaying:
The colors here change when I change the 'size' argument between 1 and 4 on this line:
GL20.glVertexAttribPointer(1, 4, GL11.GL_FLOAT, false, 0, 0);
I haven't checked all of your code, but your shaders are broken. You aren't declaring correct in variables, so you bascially use uninitialized data. Do those shaders even compile with layout qualifiers for global variables?
The vertex shader should be changed to:
layout(location=0) in vec3 pos;
layout(location=1) in vec2 tex;
and analogously for the fragment shader:
in vec2 Tex;
Note that locations are only relevant for cases where is some host <-> GL communication (like uniforms, vertex attributes and fragment shader outputs), but there are no locations for shader in- and outputs which are internal to the GL pipeline, so you cannot declare a location for fragment shader inputs. Those variables are matched by the names.

JOGL 2.0 doesn't support GLCanvas ,Texture ,Animator , but jogl 1.0 does?

I downloaded jogl 2.0 from here , the file jogl-all.jar , and ran a simple code example taken from here :
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCanvas;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.swing.JFrame;
import com.sun.opengl.util.Animator;
/**
* This is a simple example for the method
*
* glNormal();
*
*
* Keyboard commands:
*
* Key A) Increase the deltaZ value
*
* Key B) Decrease the deltaZ value
*
* Key C) Increase the deltaX value
*
* Key D) Decrease the deltaX value
*
* Key E) Increase the deltaY value
*
* Key F) Decrease the deltaY value
*
* #author Alessandro Martinelli
*/
public class Practice11IlluminateGeometry extends JFrame implements KeyListener{
private static float deltaZ=0;
private static float deltaX=0;
private static float deltaY=0;
public static void main(String[] args) {
Practice11IlluminateGeometry frame=new Practice11IlluminateGeometry();
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.setVisible(true);
}
public Practice11IlluminateGeometry(){
setSize(600,600);
setTitle("Hello Universe");
GraphicListener listener=new GraphicListener();
GLCanvas canvas = new GLCanvas(new GLCapabilities());
canvas.addGLEventListener(listener);
getContentPane().add(canvas);
Animator animator = new Animator(canvas);
animator.start();
addKeyListener(this);
}
public class GraphicListener implements GLEventListener{
public void display(GLAutoDrawable arg0) {
GL gl=arg0.getGL();
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
gl.glEnable(GL.GL_DEPTH_TEST);
gl.glCullFace(GL.GL_FRONT);
gl.glEnable(GL.GL_CULL_FACE);
gl.glFrontFace(GL.GL_CW);
gl.glLoadIdentity();
gl.glTranslatef(deltaX, deltaY, deltaZ);
gl.glColor3f(1,1,1);
gl.glBegin(GL.GL_TRIANGLE_STRIP);
gl.glNormal3f(0, 0, 1);
gl.glVertex3f(0,0,0);
gl.glVertex3f(0.3f,0,-0.4f);
gl.glVertex3f(0,0.3f,0);
gl.glVertex3f(0.3f,0.3f,0.4f);
gl.glVertex3f(0.3f,0.6f,0);
gl.glEnd();
}
public void displayChanged(GLAutoDrawable arg0, boolean arg1, boolean arg2) {
}
public void init(GLAutoDrawable arg0) {
GL gl=arg0.getGL();
gl.glEnable(GL.GL_LIGHTING);
float ambient[]= {0.2f,0.2f,0.2f,1};
gl.glLightModelfv(GL.GL_LIGHT_MODEL_AMBIENT , ambient,0);
gl.glEnable(GL.GL_LIGHT0);
float position[]= {-0.4f,0.5f,0.7f,1};
gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, position, 0);
float intensity[]= {1,1,1,1};
gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, intensity, 0);
gl.glEnable(GL.GL_LIGHT1);
float position2[]= {0,-0.8f,0.3f,1};
gl.glLightfv(GL.GL_LIGHT1, GL.GL_POSITION, position2, 0);
float intensity2[]= {1,0,0,0};
gl.glLightfv(GL.GL_LIGHT1, GL.GL_DIFFUSE, intensity2, 0);
float specIntensity2[]= {1,1,1,1};
gl.glLightfv(GL.GL_LIGHT1, GL.GL_SPECULAR, specIntensity2, 0);
gl.glEnable(GL.GL_COLOR_MATERIAL);
gl.glColorMaterial(GL.GL_FRONT_AND_BACK, GL.GL_AMBIENT_AND_DIFFUSE);
float specColor[]= {1,1,1,1};
gl.glMaterialfv(GL.GL_FRONT_AND_BACK,GL.GL_SPECULAR, specColor,0);
gl.glMaterialf(GL.GL_FRONT_AND_BACK,GL.GL_SHININESS, 80);
}
public void reshape(GLAutoDrawable arg0, int arg1, int arg2, int arg3, int arg4) {
}
}
public void keyPressed(KeyEvent arg0) {
if(arg0.getKeyCode()==KeyEvent.VK_A){
deltaZ+=0.05;
}
if(arg0.getKeyCode()==KeyEvent.VK_B){
deltaZ-=0.05;
}
if(arg0.getKeyCode()==KeyEvent.VK_C){
deltaX+=0.05;
}
if(arg0.getKeyCode()==KeyEvent.VK_D){
deltaX-=0.05;
}
if(arg0.getKeyCode()==KeyEvent.VK_E){
deltaY+=0.05;
}
if(arg0.getKeyCode()==KeyEvent.VK_F){
deltaY-=0.05;
}
}
public void keyReleased(KeyEvent arg0) {
}
public void keyTyped(KeyEvent arg0) {
}
static final long serialVersionUID=100;
}
and I got :
The import javax.media.opengl.GLCanvas cannot be resolved
The import com.sun.opengl cannot be resolved
and a few more (from other projects):
Texture cannot be resolved to a type
Animator cannot be resolved to a type
I guess that the jar doesn't support those types , why is that ? any way around this ?
This is quite weird , since version 2.0 suppose to support everything that version 1.0 supports , or am I wrong ?
Furthermore , this code works great with jogl 1.0 , but I must use version 2.0 .
Between jogl 1.1 and 2.0 the top level package name of the jogl project changed from javax.media.opengl to com.jogamp.opengl
For the two cases listed the Animator class can now be found under com.jogamp.opengl.util.Animator and Texture is now in the package com.jogamp.opengl.util.texture.Texture
The javadoc for jogl should help locate any other classes you are missing.
https://jogamp.org/deployment/jogamp-next/javadoc/jogl/javadoc/
I used the above example as template and adapted it to Jogl 2.0.
Please see code below:
import java.awt.*;
import java.awt.event.*;
import javax.media.opengl.GL;
import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLProfile;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.awt.GLCanvas;
import com.jogamp.opengl.util.Animator;
public class IlluminateGeometry extends Frame implements KeyListener {
private static float deltaZ = 0.0f;
private static float deltaX = 0.0f;
private static float deltaY = 0.0f;
static GL2 gl;
static GLCanvas canvas;
static GLCapabilities capabilities;
static GLProfile profile;
static Animator animator;
public IlluminateGeometry() {
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
animator.stop();
dispose();
System.exit(0);
}
});
profile = GLProfile.getDefault();
capabilities = new GLCapabilities(profile);
canvas = new GLCanvas(capabilities);
animator = new Animator(canvas);
GraphicListener graphiclistener = new GraphicListener();
canvas.addGLEventListener(graphiclistener);
canvas.addKeyListener(this);
add(canvas, BorderLayout.CENTER);
animator.start();
}
public class GraphicListener implements GLEventListener {
public void display(GLAutoDrawable drawable) {
gl = drawable.getGL().getGL2();
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
// Enables clearing of the depth buffer
gl.glClearDepth(1.0f);
// Z-Buffer algorithm
gl.glEnable(GL2.GL_DEPTH_TEST);
// The type of depth test to do
gl.glDepthFunc(GL2.GL_LEQUAL);
gl.glCullFace(GL2.GL_FRONT);
gl.glEnable(GL2.GL_CULL_FACE);
gl.glFrontFace(GL2.GL_CW);
gl.glLoadIdentity();
gl.glTranslatef(deltaX, deltaY, deltaZ);
gl.glColor3f(1.0f, 1.0f, 1.0f);
gl.glBegin(GL2.GL_TRIANGLE_STRIP);
gl.glNormal3f(0.0f, 0.0f, 1.0f);
gl.glVertex3f(0.0f, 0.0f, 0.0f);
gl.glVertex3f(0.3f, 0.0f, -0.4f);
gl.glVertex3f(0.0f, 0.3f, 0.0f);
gl.glVertex3f(0.3f, 0.3f, 0.4f);
gl.glVertex3f(0.3f, 0.6f, 0.0f);
gl.glEnd();
}
public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {}
public void init(GLAutoDrawable drawable) {
gl = drawable.getGL().getGL2();
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
gl.glEnable(GL2.GL_LIGHTING);
float lightAmbient[] = { 0.2f, 0.2f, 0.2f, 1.0f };
gl.glLightModelfv(GL2.GL_LIGHT_MODEL_AMBIENT, lightAmbient, 0);
gl.glEnable(GL2.GL_LIGHT0);
float lightPosition[] = { -0.4f, 0.5f, 0.7f, 1.0f };
gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_POSITION, lightPosition, 0);
float lightIntensity[] = { 1.0f, 1.0f, 1.0f, 1.0f };
gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_DIFFUSE, lightIntensity, 0);
gl.glEnable(GL2.GL_LIGHT1);
float lightPosition2[] = { 0.0f, -0.8f, 0.3f, 1.0f };
gl.glLightfv(GL2.GL_LIGHT1, GL2.GL_POSITION, lightPosition2, 0);
float lightIntensity2[] = { 1.0f, 0.0f, 0.0f, 0.0f };
gl.glLightfv(GL2.GL_LIGHT1, GL2.GL_DIFFUSE, lightIntensity2, 0);
float lightSpecularIntensity2[] = { 1.0f, 1.0f, 1.0f, 1.0f };
gl.glLightfv(GL2.GL_LIGHT1, GL2.GL_SPECULAR, lightSpecularIntensity2, 0);
gl.glEnable(GL2.GL_COLOR_MATERIAL);
gl.glColorMaterial(GL2.GL_FRONT_AND_BACK, GL2.GL_AMBIENT_AND_DIFFUSE);
float lightSpecularColor[] = { 1.0f, 1.0f, 1.0f, 1.0f };
gl.glMaterialfv(GL2.GL_FRONT_AND_BACK, GL2.GL_SPECULAR, lightSpecularColor, 0);
gl.glMaterialf(GL2.GL_FRONT_AND_BACK, GL2.GL_SHININESS, 80);
}
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {}
public void dispose(GLAutoDrawable drawable) {}
}
public void keyTyped(KeyEvent key) {}
public void keyPressed(KeyEvent key) {
switch (key.getKeyCode()) {
case KeyEvent.VK_A:
deltaZ += 0.05;
break;
case KeyEvent.VK_B:
deltaZ -= 0.05;
break;
case KeyEvent.VK_C:
deltaX += 0.05;
break;
case KeyEvent.VK_D:
deltaX -= 0.05;
break;
case KeyEvent.VK_E:
deltaY += 0.05;
break;
case KeyEvent.VK_F:
deltaY -= 0.05;
break;
default:
break;
}
}
public void keyReleased(KeyEvent key) {}
public static void main(String[] args) {
IlluminateGeometry frame = new IlluminateGeometry();
frame.setTitle("Illuminate Geometry");
frame.setSize(640, 480);
frame.setVisible(true);
}
}

Textures in OpenGL ES 2.0 for Android

I'm new to OpenGL and I'm teaching myself by making a 2D game for Android with ES 2.0. I am starting off by creating a "Sprite" class that creates a plane and renders a texture to it. To practice, I have two Sprite objects that are drawn alternating in the same place. I got this much working fine and well with ES 1.0, but now that I've switched to 2.0, I am getting a black screen with no errors. I'm exhausted trying to figure out what I'm doing wrong, but I have a strong feeling it has to do with my shaders. I'm going to dump all the relevant code here and hopefully somebody can give me an answer or some advice as to what I'm doing wrong. And if it's not immediately apparent what I'm doing wrong, perhaps some advice on how to figure it out? Thanks in advance for looking through all the code I'm about to post.
The three classes I'm posting are:
GameRenderer - the renderer for my GLSurfaceView
Shader - creates a shader program object
Sprite - creates a square and draws a texture on it
Also, I'll post my vertex and fragment shader source.
Related classes I didn't think were relevant enough to post:
GameActivity
GameView - A GLSurfaceView
GameLoopThread - My main game loop
FPSCounter - outputs the average FPS to logcat every 100 frames.
GameRender class:
package com.detour.raw;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.graphics.Bitmap;
import android.opengl.GLES20;
import android.opengl.GLU;
import android.opengl.Matrix;
import android.opengl.GLSurfaceView;
public class GameRenderer implements GLSurfaceView.Renderer{
private static final String LOG_TAG = GameRenderer.class.getSimpleName();
Context mContext;
Bitmap bitmap;
private float red = 0.0f;
private float green = 0.0f;
private float blue = 0.0f;
Shader shader;
FPSCounter fps;
Sprite sprite;
Sprite sprite2;
int x = 0;
private float[] mProjMatrix = new float[16];
private float[] mVMatrix = new float[16];
//int[] vertexShader;
//int[] fragmentShader;
//int program;
//String vShaderSource = "";
//String fShaderSource = "";
public GameRenderer(Context context){
mContext = context;
//create objects/sprites
sprite = new Sprite(mContext);
sprite2 = new Sprite(mContext);
fps = new FPSCounter();
}
#Override
public void onDrawFrame(GL10 gl) {
GLES20.glClearColor(red, green, blue, 1.0f);
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
if(x>3){
x=0;
}
if(x%2==0){
sprite.draw(gl);
}else{
sprite2.draw(gl);
}
x++;
fps.calculate();
//fps.draw(gl);
}
#Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
GLES20.glViewport(0, 0, width, height);
float ratio = (float)(width/height);
Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 0.5f, 10);
}
#Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// TODO Auto-generated method stub
GLES20.glEnable(GLES20.GL_TEXTURE_2D);
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
GLES20.glClearDepthf(1.0f);
GLES20.glDepthFunc(GLES20.GL_LEQUAL);
GLES20.glDepthMask(true);
GLES20.glEnable(GLES20.GL_CULL_FACE);
GLES20.glCullFace(GLES20.GL_BACK);
GLES20.glClearColor(red, green, blue, 1.0f);
//load sprite/object textures (preferably loop through an array of all sprites).
sprite.loadGLTexture(gl, mContext, R.drawable.raw1);
sprite2.loadGLTexture(gl, mContext, R.drawable.raw2);
Matrix.setLookAtM(mVMatrix, 0, 0, 0, -5.0f, 0.0f, 0f, 0f, 0f, 0.0f, 0.0f);
System.gc();
}
}
Shader class:
package com.detour.raw;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import android.content.Context;
import android.opengl.GLES20;
import android.util.Log;
public class Shader {
public static final String TAG = Shader.class.getSimpleName();
int program;
int vertexShader;
int fragmentShader;
String vShaderSource;
String fShaderSource;
public Shader(){
//blank constructor
//createProgram();
}
public Shader(String vs_source, String fs_source){
this.vShaderSource = vs_source;
this.fShaderSource = fs_source;
createProgram();
}
public Shader(int vs_source_id, int fs_source_id, Context context) {
StringBuffer vs = new StringBuffer();
StringBuffer fs = new StringBuffer();
try{
InputStream inputStream = context.getResources().openRawResource(vs_source_id);
BufferedReader in = new BufferedReader(new InputStreamReader(inputStream));
String read = in.readLine();
while (read != null) {
vs.append(read + "\n");
read = in.readLine();
}
vs.deleteCharAt(vs.length() - 1);
inputStream = context.getResources().openRawResource(fs_source_id);
in = new BufferedReader(new InputStreamReader(inputStream));
read = in.readLine();
while (read != null) {
fs.append(read + "\n");
read = in.readLine();
}
fs.deleteCharAt(fs.length() - 1);
}catch (Exception e){
Log.d("ERROR-readingShader", "Could not read shader: " + e.getLocalizedMessage());
}
this.vShaderSource = vs.toString();
this.fShaderSource = fs.toString();
createProgram();
}
private void createProgram(){
program = GLES20.glCreateProgram();
if(program!=0){
vertexShader = createShader(GLES20.GL_VERTEX_SHADER, vShaderSource);
fragmentShader = createShader(GLES20.GL_FRAGMENT_SHADER, fShaderSource);
GLES20.glAttachShader(program, vertexShader);
GLES20.glAttachShader(program, fragmentShader);
GLES20.glLinkProgram(program);
}else{
Log.e(TAG, "Couldn't create program.");
}
}
private int createShader(int type, String source){
int shader = GLES20.glCreateShader(type);
if(shader!=0){
GLES20.glShaderSource(shader, source);
GLES20.glCompileShader(shader);
}
return shader;
}
public int getProgram(){
return program;
}
Sprite class:
package com.detour.raw;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLES20;
import android.opengl.GLUtils;
public class Sprite {
//public static final int FRAME_WIDTH = 64;
//public static final int FRAME_HEIGHT = 64;
private static final String LOG_TAG = Sprite.class.getSimpleName();
Context mContext;
Bitmap bitmap;
private int textureLoc;
private int vertexLoc;
private int[] textures = new int[1];
//private int[] pixels;
/*private float textureCoordinates[] = {
0.0f, 0.0f,
0.0f, 1.0f,
1.0f, 1.0f,
1.0f, 0.0f};*/
private float vertices[] = {
-1.0f, 1.0f,// 0.0f,
-1.0f, -1.0f,// 0.0f,
1.0f, -1.0f,// 0.0f,
1.0f, 1.0f// 0.0f
};
private short[] indices = {
0, 1, 2,
0, 2, 3};
private FloatBuffer vertexBuffer;
//private IntBuffer textureBuffer;
private ShortBuffer indexBuffer;
Shader shader;
int program;
String vShaderSource = "";
String fShaderSource = "";
public Sprite(Context context){
mContext = context;
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
vbb.order(ByteOrder.nativeOrder());
vertexBuffer = vbb.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2);
ibb.order(ByteOrder.nativeOrder());
indexBuffer = ibb.asShortBuffer();
indexBuffer.put(indices);
indexBuffer.position(0);
}
public void draw(GL10 gl) {
GLES20.glDrawElements(GLES20.GL_TRIANGLES, indices.length, GLES20.GL_FLOAT, indexBuffer);
}
public void loadGLTexture(GL10 gl, Context context, int id){
shader = new Shader(R.raw.sprite_vs, R.raw.sprite_fs, mContext);
program = shader.getProgram();
GLES20.glUseProgram(program);
vertexLoc = GLES20.glGetAttribLocation(program, "a_position");
textureLoc = GLES20.glGetUniformLocation(program, "u_texture"); //texture
InputStream is = context.getResources().openRawResource(id);
try {
bitmap = BitmapFactory.decodeStream(is);
} finally {
try {
is.close();
is = null;
} catch (IOException e) {
}
}
//pixels = new int[(bitmap.getWidth()*bitmap.getHeight())];
//bitmap.getPixels(pixels, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
/*ByteBuffer byteBuf = ByteBuffer.allocateDirect(pixels.length * 4);
byteBuf.order(ByteOrder.nativeOrder());
textureBuffer = byteBuf.asIntBuffer();
textureBuffer.put(pixels);
textureBuffer.position(0);*/
GLES20.glDeleteTextures(1, textures, 0);
GLES20.glGenTextures(1, textures, 0);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]);
GLES20.glUniform1i(textureLoc, 0);
GLES20.glEnableVertexAttribArray(vertexLoc);
GLES20.glVertexAttribPointer(vertexLoc, 2, GLES20.GL_FLOAT, false, 0, vertexBuffer);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT);
//GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, FRAME_WIDTH, FRAME_HEIGHT, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, byteBuf);//(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
bitmap.recycle();
}
}
Vertex shader (sprite_vs.txt):
#version 110
attribute vec2 a_position;
varying vec2 v_texcoord;
void main()
{
gl_Position = vec4(a_position, 0.0, 1.0);
v_texcoord = a_position * vec2(0.5) + vec2(0.5);
}
Fragment (pixel) shader (sprite_fs.txt):
#version 110
uniform sampler2D u_texture;
varying vec2 v_texcoord;
void main()
{
gl_FragColor = texture2D(u_texture, v_texcoord);
}
Thank you so much if you actually took the time to look through this! Hopefully someone else can use this as a resource for themselves in the future, also.
A few observations/questions:
I don't know how you changed the fragment shader, but the version that is currently posted needs a precision specifier. Just add:
precision mediump float;
to the top, and it should work. Now regarding the black screen here are some questions:
When you change the glClearColor to something not black and comment out all the draw commands, does it still look black? If so, then you have a bigger problem than textures.
Second, if you ignore the texture output and try drawing each sprite as just a flat colored rectangle with no texture data, what do you get? You should be able to see some colored rectangle on the screen.
Finally, you need to bind the texture before you call glDrawElements. (Though this shouldn't matter in this example since you haven't changed the state yet.)

Categories

Resources