I have been using JOGL for a few days now and this is now becoming a major road block. I can not get shapes to draw in the correct z-order, instead, they are drawn in the order they are given to OpenGL.
I have spent the last few hours researching this and the general resolutions (and my reactions) seem to be the following:
Make sure your frustum is correct
I have double checked the frustum, it seems correct
I have switched to gluLookAt instead of a custom built frustum
I have switched to glOrthof just to make sure it is not perspective that is the problem.
I have not even set ANY view at all, instead working in the -1, 1 range that seems to be default
Make sure the following calls are in the init:
gl.glEnable(GL.GL_DEPTH_TEST);
gl.glDepthFunc(GL.GL_LEQUAL);
Make sure you are clearing the depth buffer on each redraw
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
I have provided the very basic sample of a program below where this problem is occurring. If you have JOGL and run it, you will see the red triangle at Z-position -0.5f ALWAYS on top while the triangles rotate around each other. If you swap the two triangle vertex calls, the green triangle will then always be on top.
This has been an immense headache for me so any insight will be helpful, either from JOGL or OpenGL in general, but I can't seem to see what is wrong.
Also note that for brevity I removed the proper code to destroy the window.
import java.awt.Frame;
import javax.media.opengl.GL;
import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.awt.GLCanvas;
import javax.media.opengl.glu.GLU;
import com.jogamp.opengl.util.Animator;
public class JOGLTest implements GLEventListener
{
static GLU glu = new GLU();
static GLCanvas canvas = new GLCanvas();
static Frame frame = new Frame("JOGL test");
static Animator animator = new Animator(canvas);
float rot = 0.0f;
public void display(GLAutoDrawable glDrawable)
{
final GL2 gl = glDrawable.getGL().getGL2();
rot++;
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity();
gl.glRotatef(rot, 0.0f, 1.0f, 0.0f);
gl.glBegin(GL.GL_TRIANGLES);
gl.glColor3f(0.0f, 1.0f, 0.0f);
gl.glVertex3f(0.0f, 1.0f, 0.0f);
gl.glVertex3f(-1.0f, -1.0f, 0.0f);
gl.glVertex3f(1.0f, -1.0f, 0.0f);
gl.glColor3f(1.0f, 0.0f, 0.0f);
gl.glVertex3f(-1.0f, 1.0f, -0.5f);
gl.glVertex3f(1.0f, 1.0f, -0.5f);
gl.glVertex3f(0.0f, 0.0f, -0.5f);
gl.glEnd();
}
public void dispose(GLAutoDrawable arg0)
{
}
public void init(GLAutoDrawable glDrawable)
{
GL2 gl = glDrawable.getGL().getGL2();
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
gl.glClearDepth(1.0f);
gl.glEnable(GL.GL_DEPTH_TEST);
gl.glDepthFunc(GL.GL_LEQUAL);
}
public void reshape(GLAutoDrawable arg0, int arg1, int arg2, int arg3,
int arg4)
{
}
public static void main(String[] args)
{
canvas.addGLEventListener(new JOGLTest());
frame.add(canvas);
frame.setSize(640, 480);
frame.setVisible(true);
animator.start();
canvas.requestFocus();
}
}
I have solved the problem over much deliberation.
I created a GLCapabilities object and manually set the number of bits for a depth buffer while creating a GLCanvas. The code is as follows:
GLProfile glp = GLProfile.getDefault();
GLCapabilities caps = new GLCapabilities(glp);
caps.setDepthBits(16);
canvas = new GLCanvas(caps);
Just stumbled across your question... are you using an Intel graphics card and an 'older' (pre-24th November) version of JOGL, by any chance? If so, the following may be helpful (ignore the mention of win7 64-bit; the problem described is more general and was solved in that instance in subsequent JOGL releases):
http://jogamp.762907.n3.nabble.com/Depth-buffer-not-working-on-Win7-64b-td1737435.html
Got the same problem, but unlike #david I just set the depthSize in GLData:
GLData data = new GLData ();
data.depthSize = 24;
#jogl #linux
Related
While trying to set up a minimal reproducable example using LWJGL because my original question was closed, I ran into a problem I didn't have originally (Originally it was just not displaying), which is that the JVM now crashes with an EXCEPTION_ACCESS_VIOLATION error during the glDrawArrays() call.
I don't know what could be causing this, but I've tried for example initializing the vertex attribute pointers each frame. There is also no debug information or errors logged, while I did set up an error callback and I think a debug message callback.
All of the code:
import org.lwjgl.glfw.GLFW;
import org.lwjgl.glfw.GLFWErrorCallback;
import org.lwjgl.opengl.GL;
import org.lwjgl.opengl.GL30;
import org.lwjgl.opengl.GLUtil;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
public class MinimalExample {
private static String readResource(String res) {
try {
InputStream is = MinimalExample.class.getResourceAsStream(res);
String s = new String(is.readAllBytes(), StandardCharsets.UTF_8);
is.close();
return s;
} catch (Exception e) {
throw new IllegalStateException(e);
}
}
// vertex data buffer
private static final ByteBuffer buf = ByteBuffer.allocateDirect(4096);
// shader program
static int program;
// render objects
static int vao;
static int vbo;
public static void main(String[] args) {
// set buffer limit
buf.limit(4096);
// init glfw and create window
GLFW.glfwInit();
long window = GLFW.glfwCreateWindow(500, 500, "Hello", 0, 0);
// create GL
GLFW.glfwMakeContextCurrent(window);
GL.createCapabilities();
GLUtil.setupDebugMessageCallback(System.out);
GLFW.glfwSetErrorCallback(GLFWErrorCallback.createPrint(System.out));
// create vertex objects
vao = GL30.glGenVertexArrays();
vbo = GL30.glGenBuffers();
GL30.glBindVertexArray(vao);
GL30.glVertexAttribPointer(0, 3, GL30.GL_FLOAT, false, 7 * 4, 0);
GL30.glVertexAttribPointer(1, 4, GL30.GL_FLOAT, false, 7 * 4, 0);
GL30.glEnableVertexAttribArray(0);
GL30.glEnableVertexAttribArray(1);
GL30.glBindVertexArray(0);
// compile and link shaders
int vertexShader = GL30.glCreateShader(GL30.GL_VERTEX_SHADER);
int fragmentShader = GL30.glCreateShader(GL30.GL_FRAGMENT_SHADER);
GL30.glShaderSource(vertexShader, readResource("/test.vsh"));
GL30.glShaderSource(fragmentShader, readResource("/test.fsh"));
GL30.glCompileShader(vertexShader);
GL30.glCompileShader(fragmentShader);
program = GL30.glCreateProgram();
GL30.glAttachShader(program, vertexShader);
GL30.glAttachShader(program, fragmentShader);
GL30.glLinkProgram(program);
// render loop
while (!GLFW.glfwWindowShouldClose(window)) {
// poll events
GLFW.glfwPollEvents();
// clear screen
GL30.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
GL30.glClear(GL30.GL_COLOR_BUFFER_BIT);
// render
render();
// swap buffers
GLFW.glfwSwapBuffers(window);
}
}
static void render() {
// put vertex data
// manual to simulate graphics library
putVec3(0.25f, 0.25f, 1f); putVec4(1.0f, 0.0f, 0.0f, 1.0f);
putVec3(0.75f, 0.25f, 1f); putVec4(0.0f, 1.0f, 0.0f, 1.0f);
putVec3(0.50f, 0.75f, 1f); putVec4(0.0f, 0.0f, 1.0f, 1.0f);
// bind program
GL30.glUseProgram(program);
// bind vertex array
GL30.glBindVertexArray(vao);
GL30.glEnableVertexAttribArray(0);
GL30.glEnableVertexAttribArray(1);
// upload graphics data and draw
GL30.glBindBuffer(GL30.GL_ARRAY_BUFFER, vbo);
GL30.glBufferData(GL30.GL_ARRAY_BUFFER, buf, GL30.GL_STATIC_DRAW);
GL30.glDrawArrays(GL30.GL_TRIANGLES, 0, 3);
GL30.glBindBuffer(GL30.GL_ARRAY_BUFFER, 0);
GL30.glBindVertexArray(0);
// reset vertex data buffer
buf.position(0);
}
//////////////////////////////////////////
static void putVec3(float x, float y, float z) {
buf.putFloat(x).putFloat(y).putFloat(z);
}
static void putVec4(float x, float y, float z, float w) {
buf.putFloat(x).putFloat(y).putFloat(z).putFloat(z);
}
}
The full JVM error log (hs_err_pidX.log): pastes.dev
For context, I'm running this with JDK 17 from IntelliJ directly. Here is the build.gradle file if you want to check the dependencies: build.gradle (GitHub)
Im working on my 3D Game with LibGdx.
After looking some other Threads and posts with some realy good tutorials I get the first shader working. My Problem now is to get a Cel/Outline/Toon Shader working.
Therefore I found also a tutorial and a project but they havnt worked.
After reading some posts how to solve this shading Problem (with rendering the Object twice,...) I tried this method but got some sideeffects.
Actually I got as result a darfred rendering Scene.
My Question is now, If my Models just need some other Material or why I get these results.
I wrote a cel shader based on the KBAL tutorial that results in renderings like the one above. I've been meaning to write up something on it since the library has changed a lot since then. It seems like you got stuck on the depth shader, which is one of the parts from the original tutorial that needed the most updating.
Besides compatibility updates, I removed one render pass by modifying the uber shader that comes with LibGDX to perform the discretization in the KBAL tutorial's toonify() function during the initial rendering of geometry rather than in a post pass. Aside from that it follows the same pattern.
The code below is a bare bones implementation of my cel shader code. The class is derived extends AbstractScreen which implements some base functionality for LibGDX's Screen interface. Read more about Screen's here and see the CelTutorialScreen source within a full project context here.
package com.hh.ghoststory.screen;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.assets.AssetManager;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.PerspectiveCamera;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.graphics.g3d.Environment;
import com.badlogic.gdx.graphics.g3d.Model;
import com.badlogic.gdx.graphics.g3d.ModelBatch;
import com.badlogic.gdx.graphics.g3d.ModelInstance;
import com.badlogic.gdx.graphics.g3d.environment.DirectionalLight;
import com.badlogic.gdx.graphics.glutils.FrameBuffer;
import com.badlogic.gdx.graphics.glutils.ShaderProgram;
import com.badlogic.gdx.math.Matrix4;
import com.badlogic.gdx.utils.Array;
import com.hh.ghoststory.GhostStory;
import com.hh.ghoststory.render.shaders.CelDepthShaderProvider;
import com.hh.ghoststory.render.shaders.CelLineShaderProgram;
public class CelTutorialScreen extends AbstractScreen {
private PerspectiveCamera camera = new PerspectiveCamera(67, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
private AssetManager assetManager = new AssetManager();
private Array<ModelInstance> instances = new Array<ModelInstance>();
private FrameBuffer fbo;
private TextureRegion textureRegion;
private ShaderProgram lineShader = new CelLineShaderProgram();
private SpriteBatch spriteBatch = new SpriteBatch();
private ModelBatch modelBatch = new ModelBatch(Gdx.files.classpath("com/badlogic/gdx/graphics/g3d/shaders/default.vertex.glsl").readString(), Gdx.files.internal("shaders/cel.main.fragment.glsl").readString());
private ModelBatch depthBatch = new ModelBatch(new CelDepthShaderProvider());
private Environment environment = new Environment();
public CelTutorialScreen(GhostStory game) {
super(game);
Gdx.gl.glClearColor(1.0f, 0.0f, 1.0f, 0.0f);
Gdx.gl.glClear(GL20.GL_DEPTH_BUFFER_BIT | GL20.GL_COLOR_BUFFER_BIT);
// setup camera
camera.position.set(5, 5, 5);
camera.lookAt(0, 0, 0);
camera.near = 1;
camera.far = 1000;
camera.update();
// add a light
environment.add(new DirectionalLight().set(0.8f, 0.8f, 1.8f, -1f, -0.8f, 0.2f));
// load our model
assetManager.load("models/spider.g3dj", Model.class);
loading = true;
}
#Override
public void render(float delta) {
if (loading && assetManager.update())
doneLoading();
camera.update();
Gdx.gl.glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
Gdx.gl.glClear(GL20.GL_DEPTH_BUFFER_BIT | GL20.GL_COLOR_BUFFER_BIT);
// render depth map to fbo
captureDepth();
// draw the scene
renderScene();
// put fbo texture in a TextureRegion and flip it
prepTextureRegion();
// draw the cel outlines
drawOutlines();
}
/*
* Draws the cel outlines using the CelLineShaderProgram
*/
protected void drawOutlines() {
spriteBatch.setShader(lineShader);
lineShader.setUniformf("u_size", Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
spriteBatch.begin();
spriteBatch.draw(textureRegion, 0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
spriteBatch.end();
spriteBatch.setShader(null);
}
/*
* Stores fbo texture in a TextureRegion and flips it vertically.
*/
protected void prepTextureRegion() {
textureRegion = new TextureRegion(fbo.getColorBufferTexture());
textureRegion.flip(false, true);
}
/*
* Draws the depth pass to an fbo, using a ModelBatch created with CelDepthShaderProvider()
*/
protected void captureDepth() {
fbo.begin();
Gdx.gl.glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
Gdx.gl.glClear(GL20.GL_DEPTH_BUFFER_BIT | GL20.GL_COLOR_BUFFER_BIT);
depthBatch.begin(camera);
depthBatch.render(instances);
depthBatch.end();
fbo.end();
}
/*
* Renders the scene.
*/
protected void renderScene() {
Gdx.gl.glClear(GL20.GL_DEPTH_BUFFER_BIT | GL20.GL_COLOR_BUFFER_BIT);
modelBatch.begin(camera);
modelBatch.render(instances, environment);
modelBatch.end();
}
#Override
protected void doneLoading() {
loading = false;
instances.add(new ModelInstance(assetManager.get("models/spider.g3dj", Model.class)));
}
/*
* Set camera width and height, SpriteBatch projection matrix, and reinit the FBOs
*/
#Override
public void resize(int width, int height) {
camera.position.set(camera.position);
camera.viewportWidth = width;
camera.viewportHeight = height;
camera.update();
if (fbo != null) fbo.dispose();
fbo = new FrameBuffer(Pixmap.Format.RGBA8888, Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), true);
spriteBatch.setProjectionMatrix(new Matrix4().setToOrtho2D(0, 0, width, height));
}
#Override
public void dispose() {
assetManager.dispose();
modelBatch.dispose();
depthBatch.dispose();
spriteBatch.dispose();
fbo.dispose();
lineShader.dispose();
}
}
The render performs 3 passes to create the end product.
The first is contained in the captureDepth() function.
protected void captureDepth() {
fbo.begin();
Gdx.gl.glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
Gdx.gl.glClear(GL20.GL_DEPTH_BUFFER_BIT | GL20.GL_COLOR_BUFFER_BIT);
depthBatch.begin(camera);
depthBatch.render(instances);
depthBatch.end();
fbo.end();
}
A framebuffer is started, glClear is called and then the depthBatch ModelBatch() renders the model instances (only one in this case) before the framebuffer is ended.
The depthBatch is a ModelBatch that uses a CelDepthShaderProvider, which provides a CelDepthShader. CellDepthShaderProvider is a small class that extends BaseShaderProvider and overrides createShader to return an instance of CelDepthShader, which registers and sets u_near and u_far uniforms as well as sets up the use of the cel depth vertex and fragment GLSL shaders.
I'm guessing the GLSL files are where you're running into issues. The vertex shader I linked to is the same as the KBAL vertex shader with the exception of line 125, which removed some artifacts on the cel edges:
v_depth = (pos.z + u_near) / (u_far - u_near);
The fragment shader is very similar to the one in the KBAL tutorial, but is actually copied from LibGDX's built in depth fragment shader. It's quite possible that the current LigGDX DepthShader could be used instead of my CelDepthShader, but I haven't had time to look into this.
After the first pass, the packed depth map has been captured by the FBO. The second pass is ready to be run and will draw the scene with LibGDXs' default vertex shader and a slightly modified version of its fragment shader.
The changes from the default fragment shader are in lines 140-150 where the specular value is discretized before being added to gl_FragColor:
if (specIntensity > 0.6)
specFactor = 1.0;
else if (specIntensity > 0.3)
specFactor = 0.5;
else
specFactor = 0.1;
specular *= specFactor;
And 173-182 where the overall gl_FragColor is discretized:
float intensity = max(gl_FragColor.r, max(gl_FragColor.g, gl_FragColor.b));
float factor;
if (intensity > 0.8)
factor = 1.0;
else if (intensity > 0.5)
factor = 0.8;
else if (intensity > 0.25)
factor = 0.3;
else
factor = 0.1;
And that's it for the main cel pass.
Next in render() the prepTextureRegion() function is called. This just puts the depth texture captured to our fbo into a texture region and flips it vertically before using it to draw the cel outlines in the final pass.
The final pass is performed in drawOutlines() and makes use of a SpriteBatch since we're drawing a 2d texture instead of geometry. The call to spriteBatch.setShader(lineshader) sets the SpriteBatch to use an instance of CelLineShaderProgram, another class that extends ShaderProgram. It sets a u_size uniform and uses cel.line.vertex.glsl and cel.line.fragment.glsl.
This shader program runs the Laplace filter. The vertex shader is copied from the KBAL edge shader and updated to work with newer versions of LibGDX, it passes the sampled coordinate of the depth map as well as its top, bottom, left and right neighboring texels to the fragment shader as varyings.
The fragment shader uses an updated method of unpacking the depth values based on code from the getShadowness() function here as recommended by Xoppa.
There are some improvements to this process that could be made. For one, I haven't implemented the super sampling in the original tutorial.
Also, it's not really noticeable in this still image, but once you have a controllable camera in the scene, or geometry moving around, you'll notice the per pixel lighting looks a little weird, especially with limited polygons in your geometry. There is a per-pixel lighting fragment shader in the LibGDX shadow system tests that could be used as a base to implement this with cel shading. The shadow systems might even be a good base to create a multi-pass rendering system for cel shading. And there is undoubtedly code that could be removed from the modified base LibGDX shaders I've used, as well as other optimizations and cleanup.
Hope this helps you or anyone else looking for info on multipass cel shading.
I am following this tutorial about using OpenGL for my Android application.
I am trying to make a conditional statement that will choose what to put in the triangleCoords variable based on the activity that it is being called from.
Will String gt=this.getClass().getSimpleName(); give me the current running activity when coded in a non-activity class? What format does the code display as?
How can I make the gt.equals("PlayGameType1Activity") not have a "Cannot resolve symbol 'equals'" error message.
String gt=this.getClass().getSimpleName();
// number of coordinates per vertex in this array
static final int COORDS_PER_VERTEX = 3;
static float triangleCoords[];
if(gt.equals("PlayGameType1Activity"))
{
float triangleCoords[] = { // in counterclockwise order:
1.0f, -1.0f, 0.0f, // top
-1.0f, -1.0f, 0.0f, // bottom left
-1.0f, 1.0f, 0.0f // bottom right
};
}
if(gt.equals("PlayGameType2Activity"))
{
float triangleCoords[] = { // in counterclockwise order:
1.0f, 1.0f, 0.0f, // top
-1.0f, -1.0f, 0.0f, // bottom left
-1.0f, 1.0f, 0.0f // bottom right
};
}
This is what my code looks like with the error colors
Pass a reference to the current activity into this class and use currentActivity.getClass().getName()
Put them in a method
private void myMethod() {
if(gt.equals("PlayGameType1Activity"))
{
float triangleCoords[] = { // in counterclockwise order:
1.0f, -1.0f, 0.0f, // top
-1.0f, -1.0f, 0.0f, // bottom left
-1.0f, 1.0f, 0.0f // bottom right
};
if(gt.equals("PlayGameType2Activity"))
{
float triangleCoords[] = { // in counterclockwise order:
1.0f, 1.0f, 0.0f, // top
-1.0f, -1.0f, 0.0f, // bottom left
-1.0f, 1.0f, 0.0f // bottom right
};
}
I usually pass the context of the activity to static methods in another class.
Usually in utility.
This is an example of my utility class. Hope it helps give a vivid idea
public class Utility {
public static void picassoLoader(Context context, ImageView imageView, String url){
Log.d("PICASSO", "loading image");
Picasso.with(context)
.load(url)
//.resize(30,30)
.placeholder(R.drawable.one)
.error(R.drawable.one)
.into(imageView);
}
}
Then in any activity i call
Utility.picassoLoader(this, imageview, url);
passing "this" as the context or pass getContext() method
Utility.picassoLoader(getContext(), imageview, url);
Sorry for using the picasso example, Ive not used OpenGL before
i followed those steps in order to setup and create my first project:
setup
tutorial
Here is the problematic code:
main class:
/**
*
*/
package name.wadewalker.tutorial;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.media.opengl.*;
import javax.media.opengl.awt.GLCanvas;
import javax.media.opengl.glu.GLU;
/**
* #author PTOSH
*
*/
public class openGL{
/**
* #param args
*/
GLU glu;
public static void main(String[] args) {
// TODO Auto-generated method stub
GLProfile glp = GLProfile.getDefault();
GLProfile.initSingleton();
GLCapabilities CAPS = new GLCapabilities(glp);
GLCanvas CANVAS = new GLCanvas(CAPS);
CANVAS.addGLEventListener(new newLstn());
Frame FRAME = new Frame("AWT WINDOW TEST");
FRAME.setSize(1300, 700);
FRAME.add(CANVAS);
FRAME.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent E){
System.exit(0);
}
});
FRAME.setVisible(true);
}
}
GLEventListener :
package name.wadewalker.tutorial;
import javax.media.opengl.GL;
import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.fixedfunc.GLMatrixFunc;
import javax.media.opengl.glu.GLU;
public class newLstn implements GLEventListener {
private GL2 gl;
private GLU glu;
#Override
public void display(GLAutoDrawable arg0) {
// TODO Auto-generated method stub
gl.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
gl.glLoadIdentity();
gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
gl.glLoadIdentity();
gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);
gl.glClearColor(0f,0f,0f,0f);
gl.glBegin(GL.GL_TRIANGLES);
// Font-face triangle
gl.glColor3f(1.0f, 0.0f, 0.0f); // Red
gl.glVertex3f(0.0f, 0.5f, 0.0f);
// gl.glColor3f(0.0f, 1.0f, 0.0f); // Green
gl.glVertex3f(-0.5f, -0.5f, 0.5f);
// gl.glColor3f(0.0f, 0.0f, 1.0f); // Blue
gl.glVertex3f(0.5f, -0.5f, 0.5f);
// Right-face triangle
// gl.glColor3f(1.0f, 0.0f, 0.0f); // Red
gl.glVertex3f(0.0f, 0.5f, 0.0f);
// gl.glColor3f(0.0f, 0.0f, 1.0f); // Blue
gl.glVertex3f(0.5f, -0.5f, 0.5f);
// gl.glColor3f(0.0f, 1.0f, 0.0f); // Green
gl.glVertex3f(0.5f, -0.5f, -0.5f);
// Back-face triangle
// gl.glColor3f(1.0f, 0.0f, 0.0f); // Red
// gl.glVertex3f(0.0f, 1.0f, 0.0f);
// gl.glColor3f(0.0f, 1.0f, 0.0f); // Green
// gl.glVertex3f(1.0f, -1.0f, -1.0f);
// gl.glColor3f(0.0f, 0.0f, 1.0f); // Blue
// gl.glVertex3f(-1.0f, -1.0f, -1.0f);
//
// // Left-face triangle
// gl.glColor3f(1.0f, 0.0f, 0.0f); // Red
// gl.glVertex3f(0.0f, 1.0f, 0.0f);
// gl.glColor3f(0.0f, 0.0f, 1.0f); // Blue
// gl.glVertex3f(-1.0f, -1.0f, -1.0f);
// gl.glColor3f(0.0f, 1.0f, 0.0f); // Green
// gl.glVertex3f(-1.0f, -1.0f, 1.0f);
gl.glEnd();
gl.glFlush();
// ----- Render the Pyramid -----
gl.glLoadIdentity(); // reset the model-view matrix
gl.glTranslatef(-0.6f, 0.0f, 0.0f); // translate left and into the screen
gl.glRotatef(15, -0.2f, 1.0f, 0.0f); // rotate about the y-axis
}
#Override
public void dispose(GLAutoDrawable arg0) {
// TODO Auto-generated method stub
}
#Override
public void init(GLAutoDrawable arg0) {
// TODO Auto-generated method stub
gl = arg0.getGL().getGL2(); // get the OpenGL graphics context
glu = new GLU(); // get GL Utilities
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // set background (clear) color
gl.glClearDepth(1.0f); // set clear depth value to farthest
gl.glEnable(GL.GL_DEPTH_TEST); // enables depth testing
gl.glEnable(GL.GL_CULL_FACE_MODE);
gl.glDepthFunc(GL.GL_LEQUAL); // the type of depth test to do
gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST); // best perspective correction
// gl.glShadeModel(0); // blends colors nicely, and smoothes out lighting
}
#Override
public void reshape(GLAutoDrawable arg0, int arg1, int arg2, int arg3,
int arg4) {
// float red = 0.0f; float green = 0.0f; float blue = 0.0f;
////
//// gl = arg0.getGL().getGL2();
////
//// gl.glClear(GL.GL_COLOR_BUFFER_BIT);
////
// gl.glPointSize(5.0f);
//
// for (int i=0; i<50; i++) {
//
// red -= .09f; green -= .12f; blue -= .15f;
//
// if (red < 0.15) red = 1.0f; if (green < 0.15) green = 1.0f; if (blue < 0.15) blue = 1.0f;
//
// gl.glColor3f(red, green, blue);
// gl.glBegin(GL.GL_POINTS); gl.glVertex2i((i*10), 150); gl.glEnd(); }
// TODO Auto-generated method stub
glu.gluPerspective(45.0, 15, 0.1, 100.0); // fovy, aspect, zNear, zFar
}
}
I took the source code from the tutorial and modified it, my purpose is to start drawing simple 3d shapes. Problem when I execute the code, it is not rendering depth apparently. I also noticed that the tutorial was for JOGL 2.0 and some parts of the code is not working any more like : "gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST);"
so I have to delete or comment this part of the code to see the shape in 2D.
Please if someone can show me a path to a good update tutorial, or give me some help understanding the issues I'm facing.
Thank you for your help and the effort.
Your display function has the lines:
gl.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
gl.glLoadIdentity();
gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
gl.glLoadIdentity();
This will reset both the modelview and the projection matrix to identity, so in the following, you draw directly in clip space. This means that there will be no perspective effect at all.
In your reshape callback, you have
glu.gluPerspective(45.0, 15, 0.1, 100.0); // fovy, aspect, zNear, zFar
which is meant to set up some perspective transform. But it has no effect as you overwrite that matrix in the display function. However, you also use it wrong. gluPerspective() will multiply the top matrix fo the currently selected matrix stack by some perspective transform.
What you should do is something like
gl.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
gl.glLoadIdentity();
glu.gluPerspective(45.0, 15, 0.1, 100.0); // fovy, aspect, zNear, zFar
gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
in the reshape function and completely remove the
gl.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
gl.glLoadIdentity();
from the display function.
However, this will not give the result that you might expect. Since you draw your triangles partly out of the frustum, then.
Your display function ends with
gl.glLoadIdentity(); // reset the model-view matrix
gl.glTranslatef(-0.6f, 0.0f, 0.0f); // translate left and into the screen
gl.glRotatef(15, -0.2f, 1.0f, 0.0f); // rotate about the y-axis
This code does not do anything at all. You completely have misunderstood how openGL works. It does not manage 3D objects for you, which you can later shift around in the world. It is a rendering API. And OpenGL is designed as a state machine. You set some rendering state, which affects the restulst of the draw calls. Here, you set some rendering state (the modelview matrix), but you draw nothing while this state is in effect. You must make those transforms before you issue the draw cals of the objects you want to appear transformed that way.
Note that all the things I meantioned so far are correctly used in the tutorial you linked.
Another big issue with this is that you should be aware that this code totally relies on deprecated GL. In modern GL, almost all of the GL functions you use here are gone. If you are learning OpenGL nowadays, you really should consider learning the modern way (which is not so modern anymore, we have the programmable pipeline now for a decade).
I have a cube with single texture -
public class TextureDemo implements GLEventListener, KeyListener {
private Texture texture;
}
public void init(GLAutoDrawable gLDrawable) {
String filename="Picture1.jpg"; // the FileName to open
texture=TextureIO.newTexture(new File( filename ),true);
}
public void display(GLAutoDrawable gLDrawable) {
texture.bind();
gl.glBegin(GL.GL_QUADS);
// Front Face
gl.glTexCoord2f(0.0f, 0.0f);
gl.glVertex3f(-1.0f, -1.0f, 1.0f);
gl.glTexCoord2f(2f, 0.0f);
gl.glVertex3f(1.0f, -1.0f, 1.0f);
gl.glTexCoord2f(2f, 1.0f);
gl.glVertex3f(1.0f, 1.0f, 1.0f);
gl.glTexCoord2f(0.0f, 1.0f);
gl.glVertex3f(-1.0f, 1.0f, 1.0f);
// Back Face
...
}
I trying to set multiple texture on the above cube , means after the "Front Face" , replace to another texture which will take effect on the other cube face's .
How could I accomplish this ?
You bind a new texture. That tells GL that whatever we're about to draw will use that texture.
So, create new texture for a different JPG file, then bind it, then draw some vertices.