I'm doing some beginning work with shaders in LibGDX. I'm trying to set the color manually but all I get is white.
vertex shader:
attribute vec4 a_position;
uniform mat4 u_projTrans;
void main() {
gl_Position = u_projTrans * a_position;
gl_PointSize = 10.0;
}
fragment shader:
void main()
{
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
Extremely simple as you can see. With this setup I am able to draw shapes, but they always come out white. With my fragment shader I would expect everything to be red.
Am I missing something in the libgdx stack? Is something getting overridden further up the chain by some libgdx shader defaults or something?
Screen output:
Somehow you need to pass vertex to OpenGL so LibGDX having Mesh class for this requirement. I am using SpriteBatch that having own mesh that use to draw.
Vertex Shader :
attribute vec4 a_position;
uniform mat4 u_projTrans;
void main()
{
gl_Position = u_projTrans * a_position;
}
Fragment Shader :
#ifdef GL_ES
#define LOWP lowp
precision mediump float;
#else
#define LOWP
#endif
void main()
{
gl_FragColor = vec4(1,0,0,1);
}
ShaderTest
public class ShaderTest extends ApplicationAdapter {
SpriteBatch spriteBatch;
Texture texture;
ShaderProgram shaderProgram;
#Override
public void create() {
spriteBatch=new SpriteBatch();
shaderProgram=new ShaderProgram(Gdx.files.internal("default.vertex.glsl"),Gdx.files.internal("default.fragment.glsl"));
shaderProgram.pedantic = false;
if(shaderProgram.isCompiled()) {
System.out.println("Compiled Successfully");
spriteBatch.setShader(shaderProgram);
}else {
System.out.println("Some Problem in Shader");
}
texture=new Texture("badlogic.jpg");
}
#Override
public void render() {
Gdx.gl.glClearColor(1,1,0,1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
spriteBatch.begin();
spriteBatch.draw(texture,100,100);
spriteBatch.end();
}
#Override
public void dispose() {
shaderProgram.dispose();
texture.dispose();
spriteBatch.dispose();
}
}
And the output is :
EDIT
Mesh is nothing, It is just a big array of vertices, contains value that required by OpenGL and a single vertex can hold information about Position, Color, Texture Coordinates, or whatever else we would like to pass to the shaders.
According to question you fixed colour in fragment shader that is RED so you only need to pass position of quard to OpenGL.
public class QuardTest extends ApplicationAdapter {
Mesh quard;
OrthographicCamera cam;
ShaderProgram shaderProgram;
private int Idx = 0;
private float[] verts= new float[4 * 2];
#Override
public void create() {
cam=new OrthographicCamera();
shaderProgram=new ShaderProgram(Gdx.files.internal("default.vertex.glsl"),Gdx.files.internal("default.fragment.glsl"));
if(shaderProgram.isCompiled()) {
System.out.println("Compiled Successfully");
}else {
System.out.println("Some Problem in Shader");
}
quard =new Mesh(true,4,0,new VertexAttribute(VertexAttributes.Usage.Position, 2, "a_position"));
}
#Override
public void render() {
Gdx.gl.glClearColor(1,1,0,1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
drawRect(100,100,100,100);
drawRect(250,250,50,50);
}
public void drawRect(float x, float y, float width, float height){
if (Idx ==verts.length) {
flush();
}
verts[Idx++] = x;
verts[Idx++] = y;
verts[Idx++] = x + width;
verts[Idx++] = y;
verts[Idx++] = x + width;
verts[Idx++] = y + height;
verts[Idx++] = x;
verts[Idx++] = y + height;
}
public void flush(){
if (Idx ==0)
return;
quard.setVertices(verts);
Gdx.gl.glDepthMask(false);
int vertexCount = (Idx /2);
cam.setToOrtho(false, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
shaderProgram.begin();
shaderProgram.setUniformMatrix("u_projTrans", cam.combined);
quard.render(shaderProgram, GL20.GL_TRIANGLE_FAN, 0, vertexCount);
shaderProgram.end();
Gdx.gl.glDepthMask(true);
Idx =0;
}
}
Related
I've basically followed the guide on the android docs religiously, other than a couple variable names, and that I'm rendering in a fragment. I've been spending a bit off time commenting out lines and I managed to figure out that
public static int loadShader(int type, String shaderCode) {
int shader = GLES20.glCreateShader(type);
//System.out.println(shader + " ass");
//GLES20.glShaderSource(shader, shaderCode);
//GLES20.glCompileShader(shader);
//return shader;
return 0;
}
the glCreateShader method crashes the app. It doesn't return anything, it just crashes. The type inputs are always either GLES20.GL_VERTEX_SHADER or GLES20.GL_FRAGMENT_SHADER it crashes with both.
The rest of my renderer class looks like this
public class OpenGLRenderer implements GLSurfaceView.Renderer {
private Triangle trangle;
#Override
public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {
GLES20.glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
trangle = new Triangle();
}
#Override
public void onSurfaceChanged(GL10 gl10, int i, int i1) {
}
#Override
public void onDrawFrame(GL10 gl10) {
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
//trangle.draw();
}
public static int loadShader(int type, String shaderCode) {
int shader = GLES20.glCreateShader(type);
//System.out.println(shader + " ass");
//GLES20.glShaderSource(shader, shaderCode);
//GLES20.glCompileShader(shader);
//return shader;
return 0;
}
And here's my triangle class:
public class Triangle {
private FloatBuffer vertexBuffer;
private final int shaderProgram;
private final String vertexShaderCode =
"attribute vec4 vPosition;" +
"void main() {" +
" gl_Position = vPosition;" +
"}";
private final String fragmentShaderCode =
"precision mediump float;" +
"uniform vec4 vColor;" +
"void main() {" +
" gl_FragColor = vColor;" +
"}";
static float[] triangleCoords = {
0.0f, 0.5f, 0.0f,
-0.5f,-0.3f, 0.0f,
0.5f, -0.3f, 0.0f
};
static final int coordsInVertex = 3, vertexCount = triangleCoords.length / coordsInVertex, vertexStride = coordsInVertex * 4;
private int positionHandle, colorHandle;
float color[] = {1f, 0f, 0f, 1f};
public Triangle () {
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(triangleCoords.length*4);
byteBuffer.order(ByteOrder.nativeOrder());
vertexBuffer = byteBuffer.asFloatBuffer();
vertexBuffer.put (triangleCoords);
vertexBuffer.position(0);
int vertexShader = OpenGLRenderer.loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
int fragmentShader = OpenGLRenderer.loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
shaderProgram = GLES20.glCreateProgram();
GLES20.glAttachShader(shaderProgram, vertexShader);
GLES20.glAttachShader(shaderProgram, fragmentShader);
GLES20.glLinkProgram(shaderProgram);
}
public void draw () {
GLES20.glUseProgram(shaderProgram);
positionHandle = GLES20.glGetAttribLocation(shaderProgram, "vPosition");
GLES20.glEnableVertexAttribArray(positionHandle);
GLES20.glVertexAttribPointer(positionHandle, coordsInVertex, GLES20.GL_FLOAT, false, vertexStride, vertexBuffer);
colorHandle = GLES20.glGetUniformLocation(shaderProgram, "vColor");
GLES20.glUniform4fv(colorHandle, 1, color, 0);
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
GLES20.glDisableVertexAttribArray(positionHandle);
}
}
Could someone shed some light?
Not found any issue or error in the aforementioned sources that you provided, and it is completely workable when connects with a GLSurfaceView.
I think the issue is on configuring GLSurfaceView where you must explicitly set the EGLContextClientVersion of OpenGL-ES context before setRenderer;
without eglContext program will not be performed any GL operations.
GLSurfaceView view = findViewById(R.id.glview);
view.setEGLContextClientVersion(2);
view.setRenderer(new OpenGLRenderer());
I am new to OpenGL and I just begin to try LWJGL, everything worked fine until I added the PVM matrices, I don't know why nothing shows up when I added them.
The matrices related code is commented.
Here is the code :
public class Window {
private int vaoid;
private int vbover;
private int vboind;
private int vid;
private int fid;
private int pid;
//private int pml;projection matrix location
//private int vml;view matrix location
//private int mml;model matrix location
//private Matrix4f projectionMatrix;
//private Matrix4f viewMatrix;
//private Matrix4f modelMatrix;
//private FloatBuffer projbuffer = BufferUtils.createFloatBuffer(16);
public void start() {
try {
Display.setDisplayMode(new DisplayMode(800,600));
Display.setTitle("OpenGL Try");
Display.create();
} catch (LWJGLException e) {
e.printStackTrace();
System.exit(0);
}
init();
while (!Display.isCloseRequested()) {
update();
Display.sync(60);
Display.update();
}
cleanUp();
Display.destroy();
}
public static void main(String[] argv) {
Window displayExample = new Window();
displayExample.start();
}
public void init() {
//projectionMatrix = createProjectionMatrix();
float[] vertices = {
-0.5f, 0.5f, 0f, // Left top ID: 0
-0.5f, -0.5f, 0f, // Left bottom ID: 1
0.5f, -0.5f, 0f, // Right bottom ID: 2
0.5f, 0.5f, 0f // Right left ID: 3
};
FloatBuffer verticesbuffer = BufferUtils.createFloatBuffer(vertices.length);
verticesbuffer.put(vertices);
verticesbuffer.flip();
byte[] indices = {
// Left bottom triangle
0, 1, 2,
// Right top triangle
2, 3, 0
};
ByteBuffer indicesbuffer = BufferUtils.createByteBuffer(indices.length);
indicesbuffer.put(indices);
indicesbuffer.flip();
vaoid = GL30.glGenVertexArrays();
GL30.glBindVertexArray(vaoid);
vbover = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbover);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER,verticesbuffer, GL15.GL_STATIC_DRAW);
GL20.glVertexAttribPointer(0,3,GL11.GL_FLOAT,false,0,0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER,0);
GL30.glBindVertexArray(0);
vboind = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER,vboind);
GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER,indicesbuffer,GL15.GL_STATIC_DRAW);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER,0);
vid = loadShader("./res/shader.ver",GL20.GL_VERTEX_SHADER);
fid = loadShader("./res/shader.frag",GL20.GL_FRAGMENT_SHADER);
pid = GL20.glCreateProgram();
GL20.glAttachShader(pid,vid);
GL20.glAttachShader(pid, fid);
GL20.glBindAttribLocation(pid, 0, "in_position");
GL20.glLinkProgram(pid);
GL20.glValidateProgram(pid);
//pml = GL20.glGetUniformLocation(pid, "projMatrix");
//vml = GL20.glGetUniformLocation(pid, "viewMatrix");
//mml = GL20.glGetUniformLocation(pid, "modelMatrix");
GL20.glUseProgram(pid);
//projectionMatrix.store(projbuffer);
//projbuffer.flip();
//GL20.glUniformMatrix4(pml, false, projbuffer);
GL20.glUseProgram(0);
}
public void update() {
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT|GL11.GL_DEPTH_BUFFER_BIT);
GL20.glUseProgram(pid);
//viewMatrix = createTransformationMatrix(new Vector3f(0,0,0),new Vector3f(0,0,0),1f);
//viewMatrix.store(projbuffer);projbuffer.flip();
//GL20.glUniformMatrix4(vml, false, projbuffer);
//modelMatrix = createTransformationMatrix(new Vector3f(0,0,0),new Vector3f(0,0,0),1f);
//modelMatrix.store(projbuffer);projbuffer.flip();
//GL20.glUniformMatrix4(mml, false, projbuffer);
GL30.glBindVertexArray(vaoid);
GL20.glEnableVertexAttribArray(0);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER,vboind);
GL11.glDrawElements(GL11.GL_TRIANGLES,6,GL11.GL_UNSIGNED_BYTE,0);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER,0);
GL20.glDisableVertexAttribArray(0);
GL30.glBindVertexArray(0);
GL20.glUseProgram(0);
}
public void cleanUp() {
GL20.glUseProgram(0);
GL20.glDetachShader(pid, vid);
GL20.glDetachShader(pid, fid);
GL20.glDeleteShader(vid);
GL20.glDeleteShader(fid);
GL20.glDeleteProgram(pid);
GL20.glDisableVertexAttribArray(0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GL15.glDeleteBuffers(vbover);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
GL15.glDeleteBuffers(vboind);
GL30.glBindVertexArray(0);
GL30.glDeleteVertexArrays(vaoid);
}
public int loadShader(String filePath,int type) {
StringBuilder sb = new StringBuilder();
int shaderId = 0;
try {
BufferedReader br = new BufferedReader(new FileReader(filePath));
String line="";
while((line = br.readLine())!=null) {
sb.append(line).append("\n");
}
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
shaderId = GL20.glCreateShader(type);
GL20.glShaderSource(shaderId, sb);
GL20.glCompileShader(shaderId);
return shaderId;
}
/* public Matrix4f createTransformationMatrix(Vector3f pos,Vector3f
rot,float scale) {
Matrix4f mat = new Matrix4f();
Matrix4f.scale(new Vector3f(scale,scale,scale),mat,mat);
Matrix4f.translate(pos,mat,mat);
Matrix4f.rotate((float) Math.toRadians(rot.x),new
Vector3f(1,0,0),mat,mat);
Matrix4f.rotate((float) Math.toRadians(rot.y),new
Vector3f(0,1,0),mat,mat);
Matrix4f.rotate((float) Math.toRadians(rot.z),new
Vector3f(0,0,1),mat,mat);
return mat;
}*/
/*public Matrix4f createProjectionMatrix() {
Matrix4f pm = new Matrix4f();
float fieldOfView = 60f;
float aspectRatio = (float)Display.getWidth()/(float)Display.getHeight();
float znear = 0.1f;
float zfar = 100f;
float frustumLength = zfar-znear;
float ysize = (float) (1/Math.tan(Math.toRadians(fieldOfView/2f)));
float xsize = ysize/aspectRatio;
pm.m00 = xsize;
pm.m11 = ysize;
pm.m22 = -((znear+zfar)/frustumLength);
pm.m23 = -1;
pm.m32 = -((2*znear*zfar)/frustumLength);
pm.m33 = 0;
return pm;
} */
}
And the vertex shader :
#version 150 core
in vec3 in_position;
uniform mat4 projMatrix;
uniform mat4 viewMatrix;
uniform mat4 modelMatrix;
out vec4 pass_color;
void main(void){
gl_Position = projMatrix * viewMarix * modelMatrix *
vec4(in_position,1.0);
pass_color = vec4(1,0,1,1);
}
And the fragment shader :
#version 150 core
in vec4 pass_color;
out vec4 out_color;
void main(void){
out_color = pass_color;
}
Any help is appreciated ,that block me to continue learning the new opengl stuff, thank you.
I've noticed 3 problems.
You should use an IntBuffer instead of a ByteBuffer for the indices, because you store integers in this buffer. If you change the buffer type you need to also change GL_UNSIGNED_BYTE in glDrawElements to GL_UNSIGNED_INT.
Don't bind GL_ELEMENT_ARRAY_BUFFER to 0 after binding the indices buffer.
You don't need to bind and unbind GL_ELEMENT_ARRAY_BUFFER when calling glDarwElements
I hope this helps.
I am new at openGL
I created this skybox on LWJGL but It's all black
SkyboxRenderer Class :
private static String[] TEXTURE_FILES = {"right","left","bottom","back","front"};
private RawModel cube;
private int texture;
private SkyboxShader shader;
public SkyboxRenderer(Loader loader, Matrix4f projectionMatirx) {
cube = loader.loadToVAO(VERTICES, 3);
texture = loader.loadCubeMap(TEXTURE_FILES);
shader = new SkyboxShader();
shader.start();
shader.loadProjectionMatrix(projectionMatirx);
shader.stop();
}
public void render(Camera camera){
shader.start();
shader.loadViewMatrix(camera);
GL30.glBindVertexArray(cube.getVaoID());
GL20.glEnableVertexAttribArray(0);
GL13.glActiveTexture(GL13.GL_TEXTURE0);
GL11.glBindTexture(GL13.GL_TEXTURE_CUBE_MAP, texture);
GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, cube.getVertexCount());
GL20.glDisableVertexAttribArray(0);
GL30.glBindVertexArray(0);
shader.stop();
}
Loader loadCubeMap function :
public int loadCubeMap(String[] textureFiles){
int texID = GL11.glGenTextures();
GL13.glActiveTexture(GL13.GL_TEXTURE0);
GL11.glBindTexture(GL13.GL_TEXTURE_CUBE_MAP, texID);
for(int i = 0; i < textureFiles.length;i++){
TextureData data = decodeTextureFile("res/" + textureFiles[i] + ".png");
GL11.glTexImage2D(GL13.GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL11.GL_RGBA, data.getWidth(), data.getHeight(), 0, GL11.GL_RGBA,
GL11.GL_UNSIGNED_BYTE, data.getBuffer());
}
GL11.glTexParameteri(GL13.GL_TEXTURE_CUBE_MAP, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
GL11.glTexParameteri(GL13.GL_TEXTURE_CUBE_MAP, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
GL11.glTexParameteri(GL13.GL_TEXTURE_CUBE_MAP, GL11.GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE);
GL11.glTexParameteri(GL13.GL_TEXTURE_CUBE_MAP, GL11.GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE);
textures.add(texID);
return texID;
}
private TextureData decodeTextureFile(String fileName) {
int width = 0;
int height = 0;
ByteBuffer buffer = null;
try {
FileInputStream in = new FileInputStream(fileName);
PNGDecoder decoder = new PNGDecoder(in);
width = decoder.getWidth();
height = decoder.getHeight();
buffer = ByteBuffer.allocateDirect(4 * width * height);
decoder.decode(buffer, width * 4, Format.RGBA);
buffer.flip();
in.close();
} catch (Exception e) {
e.printStackTrace();
System.err.println("Tried to load texture " + fileName + ", didn't work");
System.exit(-1);
}
return new TextureData(buffer, width, height);
}
Textures exist, but skybox is fullyblack can someone help me!
How can i fix it
I need to add more details for posting because there is too much code...
SkyboxShader :
public class SkyboxShader extends ShaderProgram{
private static final String VERTEX_FILE = "src/com/redcatengine/skybox/skyboxVertexShader.txt";
private static final String FRAGMENT_FILE = "src/com/redcatengine/skybox/skyboxFragmentShader.txt";
private int location_projectionMatrix;
private int location_viewMatrix;
public SkyboxShader() {
super(VERTEX_FILE, FRAGMENT_FILE);
}
public void loadProjectionMatrix(Matrix4f matrix){
super.loadMatrix(location_projectionMatrix, matrix);
}
public void loadViewMatrix(Camera camera){
Matrix4f matrix = Maths.createViewMatrix(camera);
matrix.m30 = 0;
matrix.m31 = 0;
matrix.m32 = 0;
super.loadMatrix(location_viewMatrix, matrix);
}
#Override
protected void getAllUniformLocations() {
location_projectionMatrix = super.getUniformLocation("projectionMatrix");
location_viewMatrix = super.getUniformLocation("viewMatrix");
}
#Override
protected void bindAttributes() {
super.bindAttribute(0, "position");
}
}
public abstract class ShaderProgram {
private int programID;
private int vertexShaderID;
private int fragmentShaderID;
private static FloatBuffer matrixBuffer = BufferUtils.createFloatBuffer(16);
public ShaderProgram(String vertexFile, String fragmentFile) {
vertexShaderID = loadShader(vertexFile, GL20.GL_VERTEX_SHADER);
fragmentShaderID = loadShader(fragmentFile, GL20.GL_FRAGMENT_SHADER);
programID = GL20.glCreateProgram();
GL20.glAttachShader(programID, vertexShaderID);
GL20.glAttachShader(programID, fragmentShaderID);
bindAttributes();
GL20.glLinkProgram(programID);
GL20.glValidateProgram(programID);
getAllUniformLocations();
}
protected abstract void getAllUniformLocations();
protected int getUniformLocation(String uniformName){
return GL20.glGetUniformLocation(programID, uniformName);
}
public void start(){
GL20.glUseProgram(programID);
}
public void stop(){
GL20.glUseProgram(0);
}
public void cleanUp(){
stop();
GL20.glDetachShader(programID, vertexShaderID);
GL20.glDetachShader(programID, fragmentShaderID);
GL20.glDeleteShader(vertexShaderID);
GL20.glDeleteShader(fragmentShaderID);
GL20.glDeleteProgram(programID);
}
protected abstract void bindAttributes();
protected void bindAttribute(int attribute, String variableName){
GL20.glBindAttribLocation(programID, attribute, variableName);
}
protected void loadInt(int location, int value){
GL20.glUniform1i(location, value);
}
protected void loadFloat(int location, float value){
GL20.glUniform1f(location, value);
}
protected void loadVector(int location, Vector3f value){
GL20.glUniform3f(location, value.x, value.y, value.z);
}
protected void load2DVector(int location, Vector2f value){
GL20.glUniform2f(location, value.x, value.y);
}
protected void loadBoolean(int location, boolean value){
float toLoad = 0;
if(value)toLoad = 1;else toLoad = 0;
GL20.glUniform1f(location, toLoad);
}
protected void loadMatrix(int location, Matrix4f matrix){
matrix.store(matrixBuffer);
matrixBuffer.flip();
GL20.glUniformMatrix4(location, false, matrixBuffer);
}
private static int loadShader(String file, int type){
StringBuilder shaderSource = new StringBuilder();
try{
BufferedReader reader = new BufferedReader(new FileReader(file));
String line;
while((line = reader.readLine()) != null){
shaderSource.append(line).append("\n");
}
reader.close();
}catch(IOException e){
System.err.println("Could not read shader file!");
e.printStackTrace();
System.exit(-1);
}
int shaderID = GL20.glCreateShader(type);
GL20.glShaderSource(shaderID, shaderSource);
GL20.glCompileShader(shaderID);
if(GL20.glGetShaderi(shaderID, GL20.GL_COMPILE_STATUS)==GL11.GL_FALSE){
System.out.println(GL20.glGetShaderInfoLog(shaderID, 500));
System.out.println("Could not compile shader.");
System.exit(-1);
}
return shaderID;
}
}
skyboxFragmentShader :
#version 400
in vec3 textureCoords;
out vec4 out_Color;
uniform samplerCube cubeMap;
void main(void){
out_Color = texture(cubeMap, textureCoords);
}
skyboxVertexShader
#version 400
in vec3 position;
out vec3 textureCoords;
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
void main(void){
gl_Position = projectionMatrix * viewMatrix * vec4(position, 1.0);
textureCoords = position;
}`
Your cube map texture is not cube complete:
Your loader code iterates over all files in the array it is called with:
for(int i = 0; i < textureFiles.length;i++){
// [...]
GL11.glTexImage2D(GL13.GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, [...])
}
However, your input array contains only 5 entires:
String[] TEXTURE_FILES = {"right","left","bottom","back","front"};
You provide only 5 faces for the cube, and forgot the "top" face.
According to the GL spec (quotes are from section 8.17 of the OpenGL 4.5 core profile specification),
A cube map texture is mipmap complete if each of the six texture
images, considered individually, is mipmap complete. Additionally, a
cube map texture is cube complete if the following conditions all hold
true:
The level_base texture images of each of the six cube map faces have identical, positive, and square dimensions.
The levelbase
images were each specified with the same internal format.
It further goes on define texture completeness:
Using the preceding definitions, a texture is complete unless any of the following
conditions hold true:
[...]
The texture is a cube map texture, and is not cube complete.
[...]
So your cube map texture is not complete.
Section 11.1.3.5 states:
If a sampler is used in a shader and the sampler’s associated texture is not
complete, as defined in section 8.17, (0; 0; 0; 1) will be returned for a non-shadow sampler and 0 for a shadow sampler.
So indeed, your cube map should appear completely black.
I have been following the Android Developer Open GL tutorial and iv just trying to draw a square in my own program as am starting to rewrite my android game in Open GL as opposed to using the Canvas class. I have encountered a problem where it wont draw the square that i am trying to draw but it will color the background.
I am trying to draw the GLSquareEntity class which is extended from the GLEntity class, below is the code
GLSquareEntity Class:
public class GLSquareEntity extends GLEntity
{
public GLSquareEntity()
{
super();
cords = new float[] {
-0.5f, 0.5f, 0.0f, // top left
-0.5f, -0.5f, 0.0f, // bottom left
0.5f, -0.5f, 0.0f, // bottom right
0.5f, 0.5f, 0.0f }; // top right
CORDS_PER_VERTEX = 3;
drawOrder = new short[] { 0, 1, 2, 0 , 2, 3 };
// Initlise the class
setup();
}
}
GLEntity Class:
public class GLEntity
{
protected final String TAG = "GLENTITY";
// Shaders
private final String vertexShaderCode =
"uniform mat4 uMVPMatrix;" +
"attribute vec4 vPosition;" +
"void main() {" +
" gl_Position = uMVPMatrix * vPosition;" +
"}";
private final String fragmentShaderCode =
"precision mediump float;" +
"uniform vec4 vColor;" +
"void main() {" +
" gl_FragColor = vColor;" +
"}";
// Open GL Variables
protected FloatBuffer vertexBuffer;
protected ShortBuffer drawListBuffer;
protected short[] drawOrder;
protected int CORDS_PER_VERTEX;
protected int vertexStride;
protected int vertexCount;
protected float[] cords;
// Just unill i can get an image to display
protected float[] color = {0.0f, 0.0f, 1.0f, 1.0f};
protected int program;
protected int positionHandle;
protected int colorHandle;
public GLEntity()
{
}
protected void setup()
{
Log.d(TAG, "GLEntity Setup");
vertexStride = CORDS_PER_VERTEX * 4;
vertexCount = cords.length / CORDS_PER_VERTEX;
// Initilise buffer for vertex cordernats
ByteBuffer vbuffer = ByteBuffer.allocateDirect(cords.length * 4);
vbuffer.order(ByteOrder.nativeOrder());
vertexBuffer = vbuffer.asFloatBuffer();
vertexBuffer.put(cords);
vertexBuffer.position(0);
// Initilise buffer for the draw list
ByteBuffer dlbuffer = ByteBuffer.allocateDirect(drawOrder.length * 2);
dlbuffer.order(ByteOrder.nativeOrder());
drawListBuffer = dlbuffer.asShortBuffer();
drawListBuffer.put(drawOrder);
drawListBuffer.position(0);
// Set up the shaders
int vertexShader = OpenGLRenderer.loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
int fragmentShader = OpenGLRenderer.loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
program = GLES20.glCreateProgram();
GLES20.glAttachShader(program, vertexShader);
GLES20.glAttachShader(program, fragmentShader);
GLES20.glLinkProgram(program);
}
public void draw()
{
//Log.d(TAG, "Drawing GL Entity");
// Select shader program to use
GLES20.glUseProgram(program);
positionHandle = GLES20.glGetAttribLocation(program, "vPosition");
GLES20.glEnableVertexAttribArray(positionHandle);
// Prepar the data
GLES20.glVertexAttribPointer(positionHandle, CORDS_PER_VERTEX, GLES20.GL_FLOAT, false, vertexStride, vertexBuffer);
// Prepare and set the color
colorHandle = GLES20.glGetUniformLocation(program, "vColor");
GLES20.glUniform4fv(colorHandle, 1, color, 0);
//GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, vertexCount);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, drawOrder.length, GLES20.GL_UNSIGNED_SHORT, drawListBuffer);
GLES20.glDisableVertexAttribArray(positionHandle);
}
}
The next classes are the GLSurfaceView class and the GLRenderer class
GLSurfaceView Class:
public class OpenGLSurfaceView extends GLSurfaceView
{
public OpenGLSurfaceView(Context context)
{
super(context);
// Set to OpenGL ES 2
setEGLContextClientVersion(2);
// Set the renderer for drawing
//OpenGLRenderer glRenderer = ;
setRenderer( new OpenGLRenderer() );
// Set to only rerender when function called
setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
}
}
OpenGLRenderer Class:
public class OpenGLRenderer implements GLSurfaceView.Renderer
{
GLPlayer player;
#Override
public void onDrawFrame(GL10 gl)
{
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
player.draw();
}
#Override
public void onSurfaceChanged(GL10 gl, int width, int height)
{
GLES20.glViewport(0, 0, width, height);
}
#Override
public void onSurfaceCreated(GL10 gl, EGLConfig config)
{
GLES20.glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
player = new GLPlayer();
}
public static int loadShader(int type, String shaderCode)
{
int shader = GLES20.glCreateShader(type);
GLES20.glShaderSource(shader, shaderCode);
GLES20.glCompileShader(shader);
return shader;
}
}
Any help figuring out what the problem is would be much appreciated :)
Thanks
I am trying to put a texture on a mesh, but failing.
I am trying to render something like this, where texture can be seen but I get this, where I can barely see the triangle. I am running the following code:
public class Game implements ApplicationListener{
Mesh mesh;
ShaderProgram shader;
Texture texture;
public static void main(String[] args) {
LwjglApplication app = new LwjglApplication(new Game(), "Mesh Tutorial 1", 800, 600, true);
}
protected static ShaderProgram createMeshShader() {
String vert = Gdx.files.internal("data/VertexShader.txt").readString();
String frag = Gdx.files.internal("data/FragmentShader.txt").readString();
ShaderProgram.pedantic = false;
ShaderProgram shader = new ShaderProgram(vert, frag);
return shader;
}
#Override
public void create() {
if (mesh == null) {
mesh = new Mesh(true, 3, 3,
new VertexAttribute(Usage.Position, 3, ShaderProgram.POSITION_ATTRIBUTE),
new VertexAttribute(Usage.Color, 4, ShaderProgram.COLOR_ATTRIBUTE),
new VertexAttribute(Usage.TextureCoordinates, 2, ShaderProgram.TEXCOORD_ATTRIBUTE));
mesh.setVertices(new float[] { -0.5f, -0.5f, 0, 0.2f, 0.3f, 0.4f, 1f, 0, 1,
0.5f, -0.5f, 0, 0.1f, 0.2f, 0.1f, 1f, 1, 1,
0, 0.5f, 0, 0, 0.4f, 0.5f, 0.5f, 1f, 0 });
mesh.setIndices(new short[] { 0, 1, 2 });
texture = new Texture(Gdx.files.internal("data/badlogic.png"));
}
shader = createMeshShader();
}
#Override
public void render() {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
Gdx.gl.glEnable(GL20.GL_TEXTURE_2D);
texture.bind();
mesh.render(shader, GL20.GL_TRIANGLES);
}
#Override
public void resize(int width, int height) {}
#Override
public void pause() {}
#Override
public void resume() {}
#Override
public void dispose() {}
The Vertexshader is:
attribute vec4 a_position;
attribute vec4 a_color;
attribute vec2 a_texCoords;
uniform mat4 u_projTrans;
varying vec4 vColor;
varying vec2 vTexCoord;
void main() {
vColor = a_color;
vTexCoord = a_texCoords;
gl_Position = u_projTrans * a_position;
}
Fragmentshader:
#ifdef GL_ES
precision mediump float;
#endif
varying vec4 v_color;
varying vec2 v_texCoords;
uniform sampler2D u_texture;
void main(){
vec4 texColor = texture2D(u_texture, v_texCoords);
gl_FragColor = v_color * texColor;
}
Correct me if I am wrong, but aren't you missing the part where you set your uniforms?
See the following as an example: OpenGlShader