Hello I am trying to render texture on two triangles. glGetError() does not return any error. I can render colored rectangle, but texture does not work. Shaders are compiled without errors. Why this code does not work? (Image)
class MainRenderer implements GLSurfaceView.Renderer {
int vertexBuffer;
int indexBuffer;
int shaderProgram;
int texture;
#Override
public void onSurfaceCreated(GL10 unused, EGLConfig config) {
GLES20.glClearColor(1, 0, 0, 1);
int[] textures = new int[1];
GLES20.glGenTextures(1, textures, 0);
texture = textures[0];
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, BitmapFactory.decodeResource(MainActivity.MainActivityHandle.getResources(), R.drawable.pes), 0);
float vertices[] = {
1, 1,
1, 0,
0, 0,
0, 1
};
int indices[] = {
0, 1, 3,
1, 2, 3
};
String vertexShaderCode = "attribute vec2 position; vec2 texturePosition; void main(){texturePosition = position;gl_Position = vec4(position,0.0, 1.0);}";
String fragmentShaderCode = "precision mediump float;uniform sampler2D texture; vec2 texturePosition; void main(){gl_FragColor = texture2D(texture, texturePosition);}";
int vertexBuffers[] = new int[1];
GLES20.glGenBuffers(1, vertexBuffers, 0);
vertexBuffer = vertexBuffers[0];
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vertexBuffer);
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, 4 * 2 * 4, FloatBuffer.wrap(vertices), GLES20.GL_STATIC_DRAW);
int indexBuffers[] = new int[1];
GLES20.glGenBuffers(1, indexBuffers, 0);
indexBuffer = indexBuffers[0];
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
GLES20.glBufferData(GLES20.GL_ELEMENT_ARRAY_BUFFER, 2 * 3 * 4, IntBuffer.wrap(indices), GLES20.GL_STATIC_DRAW);
int vertexShader = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);
GLES20.glShaderSource(vertexShader, vertexShaderCode);
GLES20.glCompileShader(vertexShader);
int fragmentShader = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
GLES20.glShaderSource(fragmentShader, fragmentShaderCode);
GLES20.glCompileShader(fragmentShader);
shaderProgram = GLES20.glCreateProgram();
GLES20.glAttachShader(shaderProgram, vertexShader);
GLES20.glAttachShader(shaderProgram, fragmentShader);
GLES20.glLinkProgram(shaderProgram);
}
#Override
public void onSurfaceChanged(GL10 unused, int width, int height) {
GLES20.glViewport(0, 0, width, height);
}
#Override
public void onDrawFrame(GL10 unused) {
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
GLES20.glUseProgram(shaderProgram);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vertexBuffer);
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture);
int positionAttributeHandle = GLES20.glGetAttribLocation(shaderProgram, "position");
GLES20.glEnableVertexAttribArray(positionAttributeHandle);
GLES20.glVertexAttribPointer(positionAttributeHandle, 2, GLES20.GL_FLOAT, false, 2*4, 0);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, 6, GLES20.GL_UNSIGNED_INT, 0);
GLES20.glDisableVertexAttribArray(positionAttributeHandle);
}
}
I can at least see that you are using (in vertex and fragment shaders) just 'vec2 texturePosition', while you should use a 'varying' for output from vertex shader to the fragment shader. Try adding 'varying' before 'vec2 ...' in shaders.
Related
So we're developing a simple game in Java using LWJGL with GLFW and OpenGL 3.3.
On AMD and Intel it works perfectly but on Nvidia it doesn't. The screen is just black (the value from glClearColor), there are neither Java-exceptions nor OpenGL-Errors.
What are we doing wrong?
Main.java:
public class Main {
Shader defaultShader;
boolean running = false;
long window;
int width = 1000;
int height = 1000;
String title = "pain";
int vao;
public static void main(String[] args){
var pain = new Pain();
pain.init();
pain.run();
}
public void init() throws RuntimeException {
GLFWErrorCallback.createPrint(System.err).set();
if (!glfwInit()) throw new RuntimeException("glfw.init.failed");
glfwDefaultWindowHints();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
this.window = glfwCreateWindow(this.width, this.height, this.title, 0, 0);
if (window == NULL) throw new RuntimeException("glfw.window.failed");
glfwMakeContextCurrent(window);
glfwSwapInterval(1);
GL.createCapabilities();
glEnable(GL_TEXTURE_2D);
this.vao = glGenVertexArrays();
glBindVertexArray(vao);
this.defaultShader = new Shader("main");
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
}
public void run() {
this.running = true;
glfwShowWindow(window);
IntBuffer width = BufferUtils.createIntBuffer(1);
IntBuffer height = BufferUtils.createIntBuffer(1);
IntBuffer comp = BufferUtils.createIntBuffer(1);
ByteBuffer data = null;
try {
data = stbi_load_from_memory(BufferCreator.createByteBuffer(FileHandler.readFileAsBytes("fuckoff/" + "heal_powerup.png")), width, height, comp, 4);
} catch (IOException ignored) {}
if (data == null) throw new RuntimeException("texture.load.failed");
int id = glGenTextures();
int twidth = width.get();
int theight = height.get();
glBindTexture(GL_TEXTURE_2D, id);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, twidth, theight, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
stbi_image_free(data);
int vid;
int tid;
int dc;
int arg4;
int[] indices = {0, 1, 2, 2, 3, 0};
dc = indices.length;
vid = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vid);
glBufferData(GL_ARRAY_BUFFER, BufferCreator.createFloatBuffer(new float[]{
0.0f, 0.0f,
100.0f, 0.0f,
100.0f, 100.0f,
0.0f, 100.0f
}), GL_DYNAMIC_DRAW);
arg4 = glGenBuffers();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, arg4);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, BufferCreator.createIntBuffer(indices), GL_STATIC_DRAW);
tid = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, tid);
glBufferData(GL_ARRAY_BUFFER, BufferCreator.createFloatBuffer(new float[]{
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f
}), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
while(this.running) {
glfwPollEvents();
glClear(GL_COLOR_BUFFER_BIT);
defaultShader.bind();
glBindTexture(GL_TEXTURE_2D, id);
this.defaultShader.setUniform("sampler", 0);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, vid);
glVertexAttribPointer(0, 2, GL_FLOAT, false, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, tid);
glVertexAttribPointer(1, 2, GL_FLOAT, false, 0, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, arg4);
glDrawElements(GL_TRIANGLES, dc, GL_UNSIGNED_INT, 0);
//Unbind buffers
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
//Disable
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glfwSwapBuffers(window);
if (glfwWindowShouldClose(window)) shutdown();
System.out.println(glGetError());
}
glfwFreeCallbacks(this.window);
glfwDestroyWindow(this.window);
glfwTerminate();
glfwSetErrorCallback(null).free();
}
void shutdown(){
this.running = false;
}
}
Shader.java:
public class Shader {
private int program, vs, fs;
public Shader(String name) {
try {
this.program = glCreateProgram();
this.vs = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(this.vs, FileHandler.readFile("shaders/" + name + ".vs"));
glCompileShader(this.vs);
if (glGetShaderi(this.vs, GL_COMPILE_STATUS) != 1) throw new RuntimeException("shader.compile.failed\n" + glGetShaderInfoLog(vs));
this.fs = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(this.fs, FileHandler.readFile("shaders/" + name + ".fs"));
glCompileShader(this.fs);
if (glGetShaderi(this.fs, GL_COMPILE_STATUS) != 1) throw new RuntimeException("shader.compile.failed" + glGetShaderInfoLog(fs));
glAttachShader(this.program, this.vs);
glAttachShader(this.program, this.fs);
glBindAttribLocation(this.program, 0, "vertices");
glBindAttribLocation(this.program, 1, "textures");
glLinkProgram(this.program);
if (glGetProgrami(this.program, GL_LINK_STATUS) != 1) throw new RuntimeException("shader.link.failed");
glValidateProgram(this.program);
if (glGetProgrami(this.program, GL_VALIDATE_STATUS) != 1) throw new RuntimeException("shader.validation.failed");
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}
}
public void updateShaderParameters() {
this.setUniform("sampler", 0);
int location = glGetUniformLocation(this.program, "windowSize");
if (location != 1) {
glUniform2f(location, 1000, 1000);
}
}
public void setUniform(String name, int value) {
int location = glGetUniformLocation(this.program, name);
if (location != -1) {
glUniform1i(location, value);
}
}
public void bind() {
glUseProgram(this.program);
this.updateShaderParameters();
}
}
Vertex Shader:
#version 330 core
layout (location = 0) in vec2 vertices;
layout (location = 1) in vec2 textures;
uniform vec2 windowSize;
out vec2 tex_coords;
void main() {
tex_coords = textures;
gl_Position = vec4(2.0/windowSize.x * vertices.x - 1.0, (2.0/windowSize.y * vertices.y - 1.0) * -1.0, 1, 1);
}
Fragment Shader:
#version 330 core
uniform sampler2D sampler;
out vec4 FragColor;
in vec2 tex_coords;
void main() {
if (texture(sampler, tex_coords).a != 1.0f) {
discard;
}
FragColor = texture(sampler, tex_coords);
}
BufferCreator.java and FileHandler.java are simple utility-classes which seem to work perfectly.
I assume, it has something to do with the Sampler because when I remove the if...discard statement in the Fragment Shader and set FragColor to some random values, it is drawn.
In your updateShaderParameters() method your checking for !=1 it should be !=-1 since windowSize location would be 1. If your checking for 1, it will never get set.
This could be an oversight or a mistype at the end. Happens to the best of us.
public void updateShaderParameters() {
this.setUniform("sampler", 0);
int location = glGetUniformLocation(this.program, "windowSize");
if (location != -1) {
glUniform2f(location, 1000, 1000);
}
}
I have some troubles with opengles 2.0. Currently I trying to display 3D teapot model without success. Method GLES20.glDrawElements generate opengl error with number 1282 and nothing is displayed on screen.
My draw method code:
public void draw(float[] tfMVPMatrix) {
GLES20.glUseProgram(miProgramID);
miVertexPositionHandle = GLES20.glGetAttribLocation(miProgramID, VertexShader.Variables.VERTEX_POSITION.getName());
miVertexTexCoordsHandle = GLES20.glGetAttribLocation(miProgramID, VertexShader.Variables.VERTEX_TEXTURE_CORDS.getName());
miVertexNormalsHandle = GLES20.glGetAttribLocation(miProgramID, VertexShader.Variables.VERTEX_NORMALS.getName());
miProjectionMatrixHandle = GLES20.glGetUniformLocation(miProgramID, VertexShader.Variables.MVP_MATRIX.getName());
miColorHandle = GLES20.glGetUniformLocation(miProgramID, FragmentShader.Variables.COLOR.getName());
GLES20.glEnableVertexAttribArray(miVertexPositionHandle);
GLES20.glVertexAttribPointer(miProgramID, 3, GLES20.GL_FLOAT, false, 3 * Float.SIZE, moVertBuff);
GLES20.glEnableVertexAttribArray(miVertexTexCoordsHandle);
GLES20.glVertexAttribPointer(miProgramID, 2, GLES20.GL_FLOAT, false, 2 * Float.SIZE, moTexCoordBuff);
GLES20.glEnableVertexAttribArray(miVertexNormalsHandle);
GLES20.glVertexAttribPointer(miProgramID, 3, GLES20.GL_FLOAT, false, 3 * Float.SIZE, moNormBuff);
GLES20.glUniform4fv(miColorHandle, 1, COLOR, 0);
GLES20.glUniformMatrix4fv(miProjectionMatrixHandle, 1, false, tfMVPMatrix, 0);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, miIndicesNumber, GLES20.GL_UNSIGNED_SHORT, moIndBuff); // opengl error 1282
GLES20.glDisableVertexAttribArray(miVertexPositionHandle);
GLES20.glDisableVertexAttribArray(miVertexTexCoordsHandle);
GLES20.glDisableVertexAttribArray(miVertexNormalsHandle);
}
Vertex shader code:
attribute vec4 vPosition;
attribute vec4 vNormal;
attribute vec2 vTexture;
varying vec2 texCoord;
varying vec4 normal;
uniform mat4 uMVPMatrix;
void main() {
gl_Position = uMVPMatrix * vPosition;
normal = vNormal;
texCoord = vTexture;
}
Fragment shader code:
precision mediump float;
varying vec4 normal;
uniform vec4 vColor;
void main() {
gl_FragColor = vColor;
}
My renderer code:
public class MyRenderer implements GLSurfaceView.Renderer {
private int GLProgramID;
private Demo3DObj oDemoTeapot;
private final float[] mMVPMatrix = new float[16];
private final float[] mProjectionMatrix = new float[16];
private final float[] mViewMatrix = new float[16];
private float fRatio;
#Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
GLProgram oProgram = new GLProgram();
GLProgramID = oProgram.build();
oDemoTeapot = new Demo3DObj(GLProgramID);
GLES20.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
}
#Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
GLES20.glViewport(0, 0, width, height);
fRatio = (float)width/height;
Matrix.frustumM(mProjectionMatrix, 0, -fRatio, fRatio, -1, 1, 3, 7);
}
#Override
public void onDrawFrame(GL10 gl) {
Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
oDemoTeapot.draw(mMVPMatrix);
}
}
I'm new in opengles world and I do not have any idea what can be wrong here. Can anybody help me solve this problem? What should I change here to display my model?
UPDATE!
Here is method, which is used to create moIndBuff:
private Buffer fillBufferI(int[] oContainer) {
ByteBuffer bb = ByteBuffer.allocateDirect(2 * oContainer.length);
bb.order(ByteOrder.LITTLE_ENDIAN);
for (int s : oContainer)
bb.putInt(s);
bb.rewind();
return bb;
}
I'm trying to make a post processing shader using a framebuffer. But when I attempt to sample the texture in the shaders it doesn't do anything.
As soon as I comment the line(in the fragment shader)
vec4 textureColour = texture(screenTexture, textureCoords);
out everything works again
FrameBuffer.java
package postprocessing;
import java.nio.ByteBuffer;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL14;
import org.lwjgl.opengl.GL30;
import org.lwjgl.opengl.GL32;
public class FrameBuffer {
protected static final int WIDTH = Display.getWidth();
private static final int HEIGHT = Display.getHeight();
private int framebuffer;
private int texture;
private int depthBuffer;
private int depthTexture;
public FrameBuffer()
{
initialise();
}
public void cleanUp()
{
GL30.glDeleteFramebuffers(framebuffer);
GL11.glDeleteTextures(texture);
GL30.glDeleteRenderbuffers(depthBuffer);
GL11.glDeleteTextures(depthTexture);
}
public int getTexture()
{
return texture;
}
public int getDepthTexture()
{
return depthTexture;
}
private void initialise()
{
framebuffer = createFrameBuffer();
texture = createTextureAttachment(WIDTH, HEIGHT);
depthBuffer = createDepthBufferAttachment(WIDTH, HEIGHT);
depthTexture = createDepthTextureAttachment(WIDTH, HEIGHT);
unbindCurrentFrameBuffer();
}
public void bindFrameBuffer(){
GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);//To make sure the texture isn't bound
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, framebuffer);
GL11.glViewport(0, 0, WIDTH, HEIGHT);
}
public void unbindCurrentFrameBuffer() {//call to switch to default frame buffer
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, 0);
GL11.glViewport(0, 0, Display.getWidth(), Display.getHeight());
}
private int createFrameBuffer() {
int frameBuffer = GL30.glGenFramebuffers();
//generate name for frame buffer
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, frameBuffer);
//create the framebuffer
GL11.glDrawBuffer(GL30.GL_COLOR_ATTACHMENT0);
//indicate that we will always render to color attachment 0
return frameBuffer;
}
private int createTextureAttachment( int width, int height) {
int texture = GL11.glGenTextures();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, texture);
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB, width, height,
0, GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, (ByteBuffer) null);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
GL32.glFramebufferTexture(GL30.GL_FRAMEBUFFER, GL30.GL_COLOR_ATTACHMENT0,
texture, 0);
return texture;
}
private int createDepthTextureAttachment(int width, int height){
int texture = GL11.glGenTextures();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, texture);
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL14.GL_DEPTH_COMPONENT32, width, height, 0, GL11.GL_DEPTH_COMPONENT, GL11.GL_FLOAT, (ByteBuffer) null);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
GL32.glFramebufferTexture(GL30.GL_FRAMEBUFFER, GL30.GL_DEPTH_ATTACHMENT, texture, 0);
return texture;
}
private int createDepthBufferAttachment(int width, int height) {
int depthBuffer = GL30.glGenRenderbuffers();
GL30.glBindRenderbuffer(GL30.GL_RENDERBUFFER, depthBuffer);
GL30.glRenderbufferStorage(GL30.GL_RENDERBUFFER, GL11.GL_DEPTH_COMPONENT, width,
height);
GL30.glFramebufferRenderbuffer(GL30.GL_FRAMEBUFFER, GL30.GL_DEPTH_ATTACHMENT,
GL30.GL_RENDERBUFFER, depthBuffer);
return depthBuffer;
}
}
FrameBufferShader.java
package postprocessing;
import shaders.ShaderProgram;
public class FrameBufferShader extends ShaderProgram {
private static final String VERTEX_FILE = "src/postprocessing/vertexShader.txt";
private static final String FRAGMENT_FILE = "src/postprocessing/fragmentShader.txt";
private int location_texture;
private int location_depthMap;
public FrameBufferShader()
{
super(VERTEX_FILE, FRAGMENT_FILE);
}
#Override
protected void getAllUniformLocations()
{
bindAttributes(0, "position");
}
#Override
protected void bindAttributes()
{
location_texture = super.getUniformLocation("screenTexture");
location_depthMap = super.getUniformLocation("depthMap");
}
public void connectTextureUnits()
{
super.loadInt(location_texture, 0);
super.loadInt(location_depthMap, 1);
}
}
FrameBufferRenderer.java
package postprocessing;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL13;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;
import models.RawModel;
import renderEngine.Loader;
public class FrameBufferRenderer {
private RawModel quad;
private FrameBufferShader shader;
private FrameBuffer fbo;
public FrameBufferRenderer(Loader loader, FrameBufferShader shader, FrameBuffer fbo)
{
this.fbo = fbo;
this.shader = shader;
setUpVAO(loader);
shader.start();
shader.connectTextureUnits();
shader.stop();
}
public void render()
{
prepareRender();
GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, quad.getVertexCount());
unbind();
}
private void prepareRender()
{
shader.start();
GL30.glBindVertexArray(quad.getVaoID());
GL20.glEnableVertexAttribArray(0);
GL13.glActiveTexture(GL13.GL_TEXTURE0);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, fbo.getTexture());
GL13.glActiveTexture(GL13.GL_TEXTURE1);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, fbo.getDepthTexture());
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
}
private void unbind()
{
GL11.glDisable(GL11.GL_BLEND);
GL20.glDisableVertexAttribArray(0);
GL30.glBindVertexArray(0);
shader.stop();
}
private void setUpVAO(Loader loader) {
float[] vertices = { -1, -1, 1, -1, 1, 1, -1, 1 };
quad = loader.loadtoVAO(vertices, 2);
}
}
Vertex Shader
#version 400
in vec2 position;
void main()
{
gl_Position = vec4(position.x, position.y, 0.0, 1.0);
}
Fragment Shader
#version 400
in vec2 textureCoords;
out vec4 outColor;
uniform sampler2D screenTexture;
uniform sampler2D depthTexture;
void main()
{
vec4 textureColour = texture(screenTexture, textureCoords);
outColor = vec4(1.0, 1.0, 1.0, 1.0);
}
You can't sample the destination texture in the shader.
What you can do is make a new texture and make that the destination texture for the previous step and use it as a normal texture in the current step.
I'm having pretty common problem by trying to texture simple Triangle with image. Here is the code:
Setup openGL:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(70,(float)width/(float)height, 0.3f, view);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);
glEnable(GL_DEPTH_TEST);
glEnable(GL_VERTEX_ARRAY);
glEnable(GL_TEXTURE_COORD_ARRAY);
glEnable(GL_TEXTURE_2D);
Mesh Class:
public class Mesh {
protected int TextureID=0;
protected int VertID=-1,TrisID=-1,TexID=-1;
protected Vector3 position,rotation,scale;
protected ArrayList<Vector3> verts;
protected ArrayList<Vector3> tris;
protected ArrayList<Vector3> uvs;
public Mesh(Vector3 position,Vector3 rotation,Vector3 scale){
verts= new ArrayList<Vector3>();
tris= new ArrayList<Vector3>();
uvs= new ArrayList<Vector3>();
this.position = position;
this.rotation=rotation;
this.scale=scale;
}
public void draw(){
glPushMatrix();{
// Translate Submatrix
glScalef(scale.X, scale.Y, scale.Z);
glRotatef(rotation.X,1,0,0);
glRotatef(rotation.Y,0,1,0);
glRotatef(rotation.Z,0,0,1);
glTranslatef(position.X, position.Y, position.Z);
//bind and pointer buffers and textures
TextureLoader.textureList.get(TextureID).bind();
glBindTexture(GL_TEXTURE_2D,TextureID);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, TexID);
glTexCoordPointer(2, GL_FLOAT, 0, 0);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, VertID);
glVertexPointer(3, GL_FLOAT, 0, 0);
int mode = GL_TRIANGLES;
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, TrisID);
//draw
glDrawElements(mode,tris.size()*3, GL_UNSIGNED_INT, 0);
}glPopMatrix();
}
public Mesh generate(){
updateVertBuffer();
updateTrisBuffer();
updateUvBuffer();
return this;
}
public void updateVertBuffer(){
if(VertID==-1)VertID= GL15.glGenBuffers();
FloatBuffer buffer = BufferUtils.createFloatBuffer(verts.size()*3);
for(int i=0;i<verts.size();i++){
buffer.put(verts.get(i).X);
buffer.put(verts.get(i).Y);
buffer.put(verts.get(i).Z);
}
buffer.flip();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER,VertID);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
}
public void updateTrisBuffer(){
if(TrisID==-1)TrisID = GL15.glGenBuffers();
IntBuffer buffer = BufferUtils.createIntBuffer(tris.size()*3);
for(int i=0;i<tris.size();i++){
buffer.put((int)tris.get(i).X);
buffer.put((int)tris.get(i).Y);
buffer.put((int)tris.get(i).Z);
}
buffer.flip();
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, TrisID);
GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, buffer,GL15.GL_STATIC_DRAW);
}
public void updateUvBuffer(){
if(TexID==-1)TexID= GL15.glGenBuffers();
FloatBuffer buffer = BufferUtils.createFloatBuffer(uvs.size()*2);
for(int i=0;i<uvs.size();i++){
buffer.put(uvs.get(i).Y);
buffer.put(uvs.get(i).Z);
}
buffer.flip();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, TexID);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
}
Drawing Meshes:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glRotatef(rot.X,1,0,0);
glRotatef(rot.Y,0,1,0);
glRotatef(rot.Z,0,0,1);
glTranslatef(pos.X,pos.Y,pos.Z);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
for(Mesh a : MHandler)a.draw(); // Simply drawing all meshes
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
Display.update();
Sample Mesh that works, but without textures on it:
Mesh m = new Mesh(new Vector3(0,0,0),new Vector3(0,0,0),new Vector3(10,10,10));
m.addVert(new Vector3(0,0,0),new Vector3(0,0,0));
m.addVert(new Vector3(0,1,0),new Vector3(0,1,0));
m.addVert(new Vector3(0,1,1),new Vector3(0,1,1));
m.addTriangle(new Vector3(0,1,2));
MHandler.add(m);
I know there's a bit too much code, but I don't really know where is excactly the problem. Since I'm new with openGL, any critics about the code would be helpful.
I load Textures using Slick if thats helpful.
I have a class file called MarkerCustom. MarkerCustom has a constructor that takes three variables of different types.
public MarkerCustom(int myInt, String, myString, BitmapData myBitmap) {
From my main Main activity i want to load a GLSurface view that will take an ArrayList of every instance of MarkerCustom that i will want to load into the GLSurface along with the data that will be passed into each instance of MarkerCustom's constructor.
Lets call the Array List myMarkers;
i need myMarkers to look like this:
myMarkers[0] = [1, "hello", bitMapData1]
myMarkers[1] = [66, "johnHandy", bitmapData2]
i am fairly new to java and its casting ect confuses me a bit having come from AS3
EDIT
So following AKhill's answer below i have edited my GLSurfaceView to accept an ArrayList as shown below. But the MarkerCustom Class needs to be created from each listed in that ArrayList in the constructor in a manner that its is accessible in the onSurfaceCreate and the onDrawFrame method of the GLSurfaceView
Please see those methods and the for loops/comments in this class below:
public class GLLayer extends GLSurfaceView implements SurfaceHolder.Callback, Camera.PreviewCallback, Renderer {
private Context context;
ArrayList <MarkerCustom> locationTags;
private PhoneOrientation phoneOri;
public GLLayer(Context context, int orientation, ArrayList<MarkerCustom> custMarkers) {
super(context);
locationTags = custMarkers;
this.context = context;
phoneOri=new PhoneOrientation(context); // sensor manager and interpreter
for(int i =0; i<locationTags.size(); i++){
//Need to create a an instance of each MarkerCustom
// something like MarkerCustom locationTags[i]; = new MarkerCustom (its params);
}
this.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
this.getHolder().setFormat(PixelFormat.TRANSLUCENT);
this.setRenderer(this);
phoneOri.start(context, orientation);
}
#Override
public void onDrawFrame(GL10 gl) {
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity();
GLU.gluLookAt(gl,0, 0, 0, 0, 0, 0, 0, 0, 0);
float floatMat[]=phoneOri.getMatrix();
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadMatrixf(floatMat, 0);
for(int i=0;i<loacationTags.size();i++){
gl.glPushMatrix();
//locationTags[i].draw(gl);
gl.glLoadMatrixf(floatMat,0);
}
gl.glPushMatrix();
}
#Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
if(height == 0) {
height = 1;
}
float ratio = (float) width / height;
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
GLU.gluPerspective(gl, 35.0f, (float)width / (float)height, 5.0f, 200.0f);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
GLU.gluLookAt(gl, 0, 1.0f, 5.0f, 0, 0, 0, 0, 1.0f, 0);
}
#Override
public void onSurfaceCreated(GL10 gl, EGLConfig arg1) {
for(int i=0;i<locationTags.size();i++){
//call each MarkerCustom's loadGLTexture Method
//locationTags[i].loadGLTexture(gl, this.context);
}
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glShadeModel(GL10.GL_SMOOTH);
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
gl.glClearDepthf(1.0f);
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glDepthFunc(GL10.GL_LEQUAL);
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_SMOOTH);
}
#Override
public void onPreviewFrame(byte[] data, Camera camera) {
}
}
And Just for reference here is my MarkerCustom class
public class MarkerCustom {
public float xPos;
public float yPos;
public float zPos;
public float yaw;
public float pitch;
public Bitmap tagImage;
private FloatBuffer vertexBuffer; // buffer holding the vertices
private float vertices[] = {
0.0f, -10.0f, -10.0f, // V1 - bottom left
0.0f, -10.0f, 10.0f, // V2 - top left
0.0f, 10.0f, -10.0f, // V3 - bottom right
0.0f, 10.0f, 10.0f // V4 - top right
};
private FloatBuffer textureBuffer; // buffer holding the texture coordinates
private float texture[] = {
// Mapping coordinates for the vertices
0.0f, 1.0f, // top left (V2)
0.0f, 0.0f, // bottom left (V1)
1.0f, 1.0f, // top right (V4)
1.0f, 0.0f // bottom right (V3)
};
public MarkerCustom(float x, float y, float z, float yawAngle, float pitchAngle, Bitmap bitmap) {
xPos = x;
yPos = y;
zPos = z;
yaw = yawAngle;
pitch = pitchAngle;
tagImage = bitmap;
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(vertices.length * 4);
byteBuffer.order(ByteOrder.nativeOrder());
vertexBuffer = byteBuffer.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
byteBuffer = ByteBuffer.allocateDirect(texture.length * 4);
byteBuffer.order(ByteOrder.nativeOrder());
textureBuffer = byteBuffer.asFloatBuffer();
textureBuffer.put(texture);
textureBuffer.position(0);
}
/** The texture pointer */
private int[] textures = new int[1];
public void loadGLTexture(GL10 gl, Context context) {
// loading texture
// Enable blending using premultiplied alpha.
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA);
// generate one texture pointer
gl.glGenTextures(1, textures, 0);
// ...and bind it to our array
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
// create nearest filtered texture
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
// Use Android GLUtils to specify a two-dimensional texture image from our bitmap
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, tagImage, 0);
// Clean up
tagImage.recycle();
}
public void draw(GL10 gl) {
// bind the previously generated texture
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
// Point to our buffers
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
// Set the face rotation
gl.glFrontFace(GL10.GL_CW);
// Point to our vertex buffer
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
// Draw the vertices as triangle strip
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3);
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
}
}
Try this.
List<MarkerCustom> myList=new ArrayList<MarkerCustom>();
MarkerCustom entry1=new MarkerCustom(myInt, myString, myBitmap);
MarkerCustom entry2=new MarkerCustom(myInt, myString, myBitmap);
myList.add(entry1);
myList.add(entry2);
Shorthand:
List<MarkerCustom> markerList = Arrays.asList(
new MarkerCustom(1, "hello", bitMapData1),
new MarkerCustom(66, "johnHandy", bitMapData2))
};
In this case I think it's easier to create a class Marker (for instance) that has three attributes.
For example:
class Marker {
int var1;
String var2;
BitmapData var3; }
This way, you are able to store an ArrayList of Markers (ArrayList), and you can access all the information you need.