This is my drawRect code:
public static void drawRect(float X, float Y, float WIDTH, float HEIGHT, float RED, float GREEN, float BLUE)
{
// clear the screen and depth buffer
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
// set the color of the quad (R,G,B,A)
GL11.glColor3f(RED, GREEN, BLUE);
// draw quad
GL11.glBegin(GL11.GL_QUADS);
GL11.glVertex2f(X,Y);
GL11.glVertex2f(X+WIDTH,Y);
GL11.glVertex2f(X+WIDTH,Y+HEIGHT);
GL11.glVertex2f(X,Y+HEIGHT);
GL11.glEnd();
}
This is what i'm doing
Renderer.drawRect(0, 0, Display.getWidth(), Display.getHeight(), 255, 255, 255);
It fills the entire screen (like it should) but the color is always black.
I suggested reading tutorials because glColor3f() expects 3 floats in the 0...1 range for color components, just like most accelerated graphics API-s. And if this one slipped, there may be confusion about other details too. But nevertheless, 255 would be still clamped to 1, so the routine does not draw a black rectangle, something is missing before (in the setup) and/or after (like a call making the drawing actually appear on screen).
LWJGL wiki has a complete example code for exactly what you are trying to do, by the way: http://wiki.lwjgl.org/wiki/LWJGL_Basics_3_(The_Quad).html
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
public class QuadExample {
public void start() {
try {
Display.setDisplayMode(new DisplayMode(800,600));
Display.create();
} catch (LWJGLException e) {
e.printStackTrace();
System.exit(0);
}
// init OpenGL
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glOrtho(0, 800, 0, 600, 1, -1);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
while (!Display.isCloseRequested()) {
// Clear the screen and depth buffer
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
// set the color of the quad (R,G,B,A)
GL11.glColor3f(0.5f,0.5f,1.0f);
// draw quad
GL11.glBegin(GL11.GL_QUADS);
GL11.glVertex2f(100,100);
GL11.glVertex2f(100+200,100);
GL11.glVertex2f(100+200,100+200);
GL11.glVertex2f(100,100+200);
GL11.glEnd();
Display.update();
}
Display.destroy();
}
public static void main(String[] argv) {
QuadExample quadExample = new QuadExample();
quadExample.start();
}
}
I've tried to implement an reaction-diffusion model on GPU with JOGL and GLSL.
I use a ping pong technique with 2 FramebufferObject ( I've tried too with one FBO and 2 Colors attachements without success).
Shader seems correct since I've tried it in unity (with some adaptations) and it works.
After one week of trying many things, i'm completely out of idea to make this code works. I'm really not specialist of JOGL, so maybe i miss something evident.
The result is an image which becomes white with time : no reaction-diffusion behaviors and I don't understand why !
Thanks in advance for helps. Here is my code :
package gpu2;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.nio.IntBuffer;
import java.nio.FloatBuffer;
import java.io.File;
import com.jogamp.opengl.GL2;
import com.jogamp.opengl.GLAutoDrawable;
import com.jogamp.opengl.GLEventListener;
import com.jogamp.opengl.awt.GLCanvas;
import com.jogamp.opengl.glu.GLU;
import com.jogamp.opengl.util.FPSAnimator;
import com.jogamp.opengl.GLFBODrawable;
import com.jogamp.opengl.FBObject;
import com.jogamp.opengl.FBObject.Colorbuffer;
import com.jogamp.opengl.FBObject.ColorAttachment;
import com.jogamp.opengl.FBObject.TextureAttachment;
import com.jogamp.opengl.util.glsl.ShaderCode;
import com.jogamp.opengl.util.glsl.ShaderProgram;
import com.jogamp.opengl.util.glsl.ShaderUtil;
import com.jogamp.opengl.util.GLBuffers;
import com.jogamp.opengl.util.texture.Texture;
import com.jogamp.opengl.util.texture.TextureIO;
import com.jogamp.opengl.GLCapabilities;
import com.jogamp.opengl.GLOffscreenAutoDrawable;
import com.jogamp.opengl.GLProfile;
import com.jogamp.opengl.util.awt.AWTGLReadBufferUtil;
import com.jogamp.opengl.GLDrawableFactory;
import static com.jogamp.opengl.GL.*; // GL constants
import static com.jogamp.opengl.GL2.*; // GL2 constants
import gpu2.ModelParam;
/**
* JOGL 2.0 Program Template (GLCanvas)
* This is a "Component" which can be added into a top-level "Container".
* It also handles the OpenGL events to render graphics.
*/
#SuppressWarnings("serial")
public class JOGL2Setup_GLCanvas extends GLCanvas implements GLEventListener {
// Define constants for the top-level container
private static String TITLE = "JOGL 2.0 Setup (GLCanvas)"; // window's title
private static final int CANVAS_WIDTH = 512; // width of the drawable
private static final int CANVAS_HEIGHT = 512; // height of the drawable
private static final int FPS = 30; // animator's target frames per second
private final float[] canvasVertices = {
-1f, -1f, 0.0f,
-1f, 1f, 0.0f,
1f, -1f, 0.0f,
1f, 1f, 0.0f,
};
private final float[] canvasTexCoords = {
0.0f, 0.0f,
0.0f, 1.0f,
1.0f, 0.0f,
1.0f, 1.0f,
};
/** The entry main() method to setup the top-level container and animator */
public static void main(String[] args) {
// Run the GUI codes in the event-dispatching thread for thread safety
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
// Create the OpenGL rendering canvas
GLCanvas canvas = new JOGL2Setup_GLCanvas();
canvas.setPreferredSize(new Dimension(CANVAS_WIDTH, CANVAS_HEIGHT));
// Create a animator that drives canvas' display() at the specified FPS.
final FPSAnimator animator = new FPSAnimator(canvas, FPS, true);
// Create the top-level container
final JFrame frame = new JFrame(); // Swing's JFrame or AWT's Frame
frame.getContentPane().add(canvas);
frame.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
// Use a dedicate thread to run the stop() to ensure that the
// animator stops before program exits.
new Thread() {
#Override
public void run() {
if (animator.isStarted()) animator.stop();
System.exit(0);
}
}.start();
}
});
frame.setTitle(TITLE);
frame.pack();
frame.setVisible(true);
animator.start(); // start the animation loop
}
});
}
// Setup OpenGL Graphics Renderer
private GLU glu; // for the GL Utility
private GL2 gl;
//OpenGl data
private int vboVertices;
private int vboTextCoord;
private Texture textureFile;
private FBObject fbo[];
private ShaderProgram shaderCompute;
private ShaderProgram shaderVisu;
private ShaderProgram shaderComputeInit;
private int currentSourceBuffer = 0;
private int currentDestBuffer = 1;
private int currentFrame = 0;
private int maxFrameCount = 5000000;
private float clearUniform = 0;
ModelParam params = new ModelParam();
public JOGL2Setup_GLCanvas() {
this.addGLEventListener(this);
}
#Override
public void init(GLAutoDrawable drawable) {
gl = drawable.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.glEnable(GL_TEXTURE_2D);
gl.glEnable( GL_COLOR_MATERIAL );
gl.glEnable( GL_FRAMEBUFFER );
gl.glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NEAREST); // best perspective correction
viewOrtho(gl);
gl.glViewport(0,0,CANVAS_WIDTH,CANVAS_HEIGHT);
int[] buffers = new int[2];
gl.glGenBuffers(2, buffers, 0);
vboVertices = buffers[0];
vboTextCoord = buffers[1];
gl.glBindBuffer(GL_ARRAY_BUFFER, vboVertices);
gl.glBufferData(GL_ARRAY_BUFFER, canvasVertices.length*(Float.SIZE/Byte.SIZE)*3, FloatBuffer.wrap(canvasVertices), GL_STATIC_DRAW);
gl.glBindBuffer(GL_ARRAY_BUFFER, vboTextCoord);
gl.glBufferData(GL_ARRAY_BUFFER, canvasTexCoords.length*(Float.SIZE/Byte.SIZE)*2, FloatBuffer.wrap(canvasTexCoords), GL_STATIC_DRAW);
gl.glBindBuffer( GL_ARRAY_BUFFER, 0 );
// ------------ create Texture Source------------------------
textureFile = initializeTexture();
if (textureFile==null) {
System.out.println("cannot load texture from disk");
}
// ------------ load shaders ------------------------
shaderCompute = loadShader(gl, "compute.vsh", "compute.fsh");
shaderComputeInit = loadShader(gl, "compute.vsh", "computeInit.fsh");
shaderVisu = loadShader(gl, "visu.vsh", "visu.fsh");
// ------------ create FBO ------------------------
initFBO();
}
/**
* Called back by the animator to perform rendering.
*/
#Override
public void display(GLAutoDrawable drawable) {
if (currentFrame < maxFrameCount) {
prepareNextStep();
renderToFBO();
currentFrame++;
}
renderFBOToScreen();
}
private void prepareNextStep() {
currentSourceBuffer = 1 - currentSourceBuffer;
currentDestBuffer = 1 - currentDestBuffer;
}
private void renderToFBO()
{
fbo[currentDestBuffer].bind(gl);
//gl.glClear(GL_COLOR_BUFFER_BIT);
viewOrtho(gl);
shaderCompute.useProgram(gl, true);
setShaderUniformFloat(gl, shaderCompute.program(), "diffuseU", 0.211f);
setShaderUniformFloat(gl, shaderCompute.program(), "diffuseV", 0.088f);
setShaderUniformFloat(gl, shaderCompute.program(), "feed", 0.007f);
setShaderUniformFloat(gl, shaderCompute.program(), "kill", 0.08f);
setShaderUniformFloat(gl, shaderCompute.program(), "Tech", 1f);
setShaderUniformFloat(gl, shaderCompute.program(), "currentFrame", currentFrame);
setShaderUniformFloat2(gl, shaderCompute.program(), "resolution", CANVAS_WIDTH, CANVAS_HEIGHT);
drawDataBuffer(shaderCompute, true);
shaderCompute.useProgram(gl, false);
fbo[currentDestBuffer].unbind(gl);
}
void drawDataBuffer(ShaderProgram currentShader, boolean sencondImage) {
// --- draw vbo
gl.glEnableClientState(GL_VERTEX_ARRAY);
gl.glEnableClientState(GL_TEXTURE_COORD_ARRAY);
//textcoords
gl.glBindBuffer(GL_ARRAY_BUFFER,vboTextCoord);
gl.glTexCoordPointer(2, GL_FLOAT, 0, 0);
//vertices
gl.glBindBuffer( GL_ARRAY_BUFFER, vboVertices );
gl.glVertexPointer(3, GL_FLOAT, 0, 0);
//activate texture data from last fbo
final FBObject.Colorbuffer texSource = (FBObject.Colorbuffer) fbo[currentSourceBuffer].getColorbuffer(0);
gl.glActiveTexture(GL_TEXTURE0);
gl.glBindTexture(GL_TEXTURE_2D, texSource.getName());
setShaderUniform1i(gl, currentShader.program(), "textureData", 0);
if (sencondImage) {
//activate texture with image from file
gl.glActiveTexture(GL_TEXTURE1);
gl.glBindTexture(GL_TEXTURE_2D, textureFile.getTextureObject());
textureFile.bind(gl);
setShaderUniform1i(gl, currentShader.program(), "textureImage", 1);
}
//draw buffer on screens
gl.glDrawArrays(GL_TRIANGLE_STRIP, 0, canvasVertices.length / 3);
//disable texture image
if (sencondImage) {
gl.glActiveTexture(GL_TEXTURE1);
textureFile.disable(gl);
}
//disable texture data
gl.glActiveTexture(GL_TEXTURE0);
gl.glDisable(texSource.getName());
gl.glDisableClientState(GL_TEXTURE_COORD_ARRAY);
gl.glDisableClientState(GL_VERTEX_ARRAY);
}
public void renderFBOToScreen()
{
gl.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear color and depth buffers
gl.glLoadIdentity(); // reset the model-view matrix
viewOrtho(gl);
gl.glEnable(GL_TEXTURE_2D);
final FBObject.Colorbuffer tex0 = (FBObject.Colorbuffer) fbo[currentDestBuffer].getColorbuffer(0);
gl.glActiveTexture(GL_TEXTURE0);
gl.glBindTexture(GL_TEXTURE_2D, tex0.getName());
//activate shader
shaderVisu.useProgram(gl, true);
// --- draw vbo
gl.glEnableClientState(GL_VERTEX_ARRAY);
gl.glEnableClientState(GL_TEXTURE_COORD_ARRAY);
//textcoords
gl.glBindBuffer(GL_ARRAY_BUFFER, vboTextCoord);
gl.glTexCoordPointer(2, GL_FLOAT, 0, 0);
//vertices
gl.glBindBuffer( GL_ARRAY_BUFFER, vboVertices );
gl.glVertexPointer(3, GL_FLOAT, 0, 0);
//draw buffer on screens
gl.glDrawArrays(GL_TRIANGLE_STRIP, 0, canvasVertices.length / 3);
gl.glDisableClientState(GL_TEXTURE_COORD_ARRAY);
gl.glDisableClientState(GL_VERTEX_ARRAY);
gl.glBindBuffer( GL_ARRAY_BUFFER, 0 );
//desactivate shader
shaderVisu.useProgram(gl, false);
}
private void initFBO()
{
try {
gl.glEnable(GL_TEXTURE_2D);
fbo = new FBObject[2];
//first fbo
fbo[currentSourceBuffer] = new FBObject(); // Create FrameBuffer
fbo[currentSourceBuffer].init(gl, CANVAS_WIDTH, CANVAS_HEIGHT, 0);
fbo[currentSourceBuffer].reset(gl, CANVAS_WIDTH, CANVAS_HEIGHT, 0); // int width, height - size of FBO, can be resized with the same call
fbo[currentSourceBuffer].bind(gl);
int tex = genTexture(gl);
gl.glBindTexture(GL_TEXTURE_2D, tex);
gl.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, CANVAS_WIDTH, CANVAS_HEIGHT, 0, GL_RGBA, GL_FLOAT, null);
fbo[currentSourceBuffer].attachTexture2D(gl, 0, GL_RGBA32F, GL_RGBA, GL_FLOAT, GL_NEAREST, GL_NEAREST, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
//gl.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
int DrawBuffers[] = {GL_COLOR_ATTACHMENT0};
gl.glDrawBuffers(1, DrawBuffers, 0); // "1" is the size of DrawBuffers
fbo[currentSourceBuffer].unbind(gl);
//second fbo
fbo[currentDestBuffer] = new FBObject(); // Create FrameBuffer
fbo[currentDestBuffer].init(gl, CANVAS_WIDTH, CANVAS_HEIGHT, 0);
fbo[currentDestBuffer].reset(gl, CANVAS_WIDTH, CANVAS_HEIGHT, 0); // int width, height - size of FBO, can be resized with the same call
fbo[currentDestBuffer].bind(gl);
tex = genTexture(gl);
gl.glBindTexture(GL_TEXTURE_2D, tex);
gl.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, CANVAS_WIDTH, CANVAS_HEIGHT, 0, GL_RGBA, GL_FLOAT, null);
fbo[currentDestBuffer].attachTexture2D(gl, 0, GL_RGBA32F, GL_RGBA, GL_FLOAT, GL_NEAREST, GL_NEAREST, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
//ogl.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
gl.glDrawBuffers(1, DrawBuffers, 1); // "1" is the size of DrawBuffers
fbo[currentDestBuffer].unbind(gl);
} catch (Exception e) {
System.out.println("Problem with fbo init " + e);
e.printStackTrace();
}
}
private Texture initializeTexture() {
Texture t = null;
try {
t = TextureIO.newTexture(new File("e:/shaders/wiki.jpg"), false);
t.setTexParameteri(gl, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
t.setTexParameteri(gl, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
t.setTexParameteri(gl, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
t.setTexParameteri(gl, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
} catch (Exception e) {
System.out.println("Unable to read texture file: " + e);
e.printStackTrace();
}
return t;
}
private ShaderProgram loadShader(GL2 gl, String vertexShader, String fragmentShader)
{
ShaderCode vertShader = ShaderCode.create(gl, GL2.GL_VERTEX_SHADER, 1, getClass(), new String[]{"e:/shaders/"+vertexShader},false);
vertShader.compile(gl);
ShaderCode fragShader = ShaderCode.create(gl, GL2.GL_FRAGMENT_SHADER, 1, getClass(), new String[]{"e:/shaders/"+fragmentShader},false);
fragShader.compile(gl);
ShaderProgram newShader = new ShaderProgram();
newShader.init(gl);
newShader.add(vertShader);
newShader.add(fragShader);
newShader.link(gl, System.out);
vertShader.destroy(gl);
fragShader.destroy(gl);
return newShader;
}
public static void setShaderUniform1i(GL2 inGL,int inProgramID,String inName,int inValue) {
int tUniformLocation = inGL.glGetUniformLocation(inProgramID,inName);
if (tUniformLocation != -1) {
inGL.glUniform1i(tUniformLocation, inValue);
} else {
System.out.println("UNIFORM COULD NOT BE FOUND! NAME="+inName);
}
}
public static void setShaderUniformFloat(GL2 inGL,int inProgramID,String inName,float inValue) {
int tUniformLocation = inGL.glGetUniformLocation(inProgramID,inName);
if (tUniformLocation != -1) {
inGL.glUniform1f(tUniformLocation, inValue);
} else {
System.out.println("UNIFORM COULD NOT BE FOUND! NAME="+inName);
}
}
public static void setShaderUniformFloat2(GL2 inGL,int inProgramID,String inName,float inValue1 ,float inValue2) {
int tUniformLocation = inGL.glGetUniformLocation(inProgramID,inName);
if (tUniformLocation != -1) {
inGL.glUniform2f(tUniformLocation, inValue1, inValue2);
} else {
System.out.println("UNIFORM COULD NOT BE FOUND! NAME="+inName);
}
}
private void viewOrtho(GL2 gl) // Set Up An Ortho View
{
gl.glMatrixMode(GL_PROJECTION); // Select Projection
gl.glPushMatrix(); // Push The Matrix
gl.glLoadIdentity(); // Reset The Matrix
gl.glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
gl.glMatrixMode(GL_MODELVIEW); // Select Modelview Matrix
gl.glPushMatrix(); // Push The Matrix
gl.glLoadIdentity(); // Reset The Matrix
}
private int genTexture(GL2 gl) {
final int[] tmp = new int[1];
gl.glGenTextures(1, tmp, 0);
return tmp[0];
}
/**
* Called back before the OpenGL context is destroyed. Release resource such as buffers.
*/
#Override
public void dispose(GLAutoDrawable drawable) { }
}
And the corresponding GLSL Shader :
#version 120
uniform sampler2D textureData;
uniform sampler2D textureImage;
uniform vec2 resolution;
uniform float diffuseU;
uniform float diffuseV;
uniform float feed;
uniform float kill;
uniform float Tech = 1.0;
uniform float currentFrame = 0.0;
void main() {
//coords
vec2 position = ( gl_FragCoord.xy / resolution.xy );
vec2 pixel = 1./resolution;
//get data from texture
vec4 imgSource = texture2D(textureImage, gl_TexCoord[0].st);
vec2 oldUV = texture2D(textureData, gl_TexCoord[0].st).rg;
if(currentFrame<10){
if (distance(position,vec2(0.5,0.5 - currentFrame * 0.01f)) < 0.2f)
oldUV = vec2(0.0,0.2);
else if (distance(position,vec2(0.5,0.5 - currentFrame * 0.01f)) < 0.3f)
oldUV = vec2(0.5,0.1);
else
oldUV = vec2(0.1,0.0);
gl_FragColor = vec4(oldUV.rg, 0.0, 1.0);
return;
}
//get neightboors
vec2 dataUp = texture2D(textureData, position + pixel * vec2(0., 1.)).rg;
vec2 dataDown = texture2D(textureData, position + pixel * vec2(0., -1.)).rg;
vec2 dataLeft = texture2D(textureData, position + pixel * vec2(-1., 0.)).rg;
vec2 dataRight = texture2D(textureData, position + pixel * vec2(1., 0.)).rg;
//adapt parameters
vec2 imgParam = imgSource.rg;
float dU = diffuseU ;//+ 0.01 * (imgParam - 0.5);
float dV = diffuseV ;//+ 0.01 * (imgParam - 0.5);
float F = feed ;//+ 0.01 * (imgParam - 0.5);
float K = kill ;//+ 0.01 * (imgParam - 0.5);
//compute new values
vec2 laplace = (dataUp+dataDown+dataLeft+dataRight) - 4.0 * oldUV;
float uvv = oldUV.r * oldUV.g * oldUV.g;
// calculate delta quantities
float du = dU * laplace.r - uvv + F*(1.0 - oldUV.r);
float dv = dV * laplace.g + uvv - (F+K)*oldUV.g;
vec2 newUV = oldUV + vec2(du, dv)* Tech;
gl_FragColor = vec4(newUV.rg, 0.0, 1.0);
}
Few considerations:
avoid deprecated OpenGL (and GLU), use GL4 (or GL3)
unless you need awt/swt/swing, prefer newt, more here
prefer Animator instead of FPSAnimator, more here
prefer direct buffers instead of arrays, since otherwise jogl has to create them underneath and you can't keep trace (= deallocate when done) of those native allocations
GL4 will allow you also to avoid all those uniform overhead (and also potential bugs) you have to deal with (especially during runtime), thanks to explicit locations
prefer direct buffer management instead of FBObject for the moment unless you really know what FBObject is doing. Once you get it working, you can move on using that class. This may be (one of the) cause your code is not working, because something is not getting setup up as you need. Moreover, the lines of codes needed to replace FBObject are essentially the same
(if you can't use explicit location for any reason) prefer some literal way to define the texture uniform location, it is usually another tricky part causing bugs, something like this
prefer also a sampler for the textures, gives you more flexibility
don't wait one week next time, let us know earlier! :) Frustation can be a nasty thing that put you down easily. Together we can help you getting it working ;)
I'm trying to fill a torus texture of wood, but leaves only one color:
img http://dl.dropbox.com/u/70996029/Screenshots/Screenshot-2012-04-12_01.28.44.png
The image is 128x128 png. What am I doing wrong?
public void init(GLAutoDrawable drawable) {
gl = drawable.getGL().getGL2();
gl.glEnable(GL2.GL_DEPTH_TEST);
gl.glDepthFunc(GL2.GL_LESS);
gl.glEnable(GL2.GL_LIGHTING);
gl.glEnable(GL2.GL_LIGHT0);
gl.glMatrixMode(GL2.GL_PROJECTION);
gl.glOrtho(-17.0, 17.0, -17.0, 17.0, -17.0, 17.0);
gl.glMatrixMode(GL2.GL_MODELVIEW);
}
public void display(GLAutoDrawable drawable)
{
gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);
float mat_diffuse[] = { 0.5f, 0.5f, 0.8f, 1.0f };
gl.glMaterialfv(GL2.GL_FRONT, GL2.GL_DIFFUSE, mat_diffuse, 0);
glut.glutSolidTorus(2, 5, 80, 80);
gl.glRotatef(90, 1, 0, 0);
gl.glTranslatef(5, 0, 0);
Texture texture = null;
try {
texture = TextureIO.newTexture(new File("D:\\Program Files\\eclipse\\projects\\rotation OGL\\src\\wood.png"), true);
texture.setTexParameterf(gl, GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_LINEAR);
texture.setTexParameterf(gl, GL2.GL_TEXTURE_MAG_FILTER, GL2.GL_LINEAR);
} catch (Exception e) {
e.printStackTrace();
}
gl.glEnable(GL2.GL_TEXTURE_2D);
texture.bind(gl);
texture.enable(gl);
glut.glutSolidTorus(2, 5, 80, 80);
texture.disable(gl);
}
Try generating some texture coordinates for your geometry.
glutSolidTorus() does not generate any for you.
I'm working on a 2D game in LWJGL. I have successfully rendered QUADS with textures using glBegin but moving to VBOs turned out to be a big undertaking. At the moment I can switch between the vbo and non-vbo rendering with a boolean, both using the same vertex- and texture coordinates. The VBO-implementation won't draw anything onto the screen. Can anyone point me in the right direction?
This is my initialization:
public void init() {
VBOID = VBOHandler.createVBOID();
TBOID = VBOHandler.createVBOID();
float[] vdata = {0, 0,
width, 0,
width, height,
0, height};
float[] tdata = {sx, sy,
ex, sy,
ex, ey,
sx, ey};
//Texture coordinates: (0,0)(1,0)(1,1) and (0,1)
FloatBuffer fb = BufferUtils.createFloatBuffer(8);
fb.put(vdata);
VBOHandler.bufferData(VBOID, fb);
fb = BufferUtils.createFloatBuffer(8);
fb.put(tdata);
VBOHandler.bufferData(TBOID, fb);
}
And here is my rendering code:
private void render() {
texture.bind();
if(vbo) {
GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
VBOHandler.bindBuffer(VBOID);
GL11.glVertexPointer(2, GL11.GL_FLOAT, 0, 0);
VBOHandler.bindBuffer(TBOID);
GL11.glTexCoordPointer(2, GL11.GL_FLOAT, 0, 0);
VBOHandler.bindElementBuffer(VBOHandler.getDefaultIBOID());
// I figured why not use a standard IBO for all my sprite drawing
// The default IBO ID is initialized earlier in the program, not shown in this code
GL12.glDrawRangeElements(GL11.GL_TRIANGLE_FAN, 0, 3, 4, GL11.GL_UNSIGNED_SHORT, 0);
GL11.glDisableClientState(GL11.GL_VERTEX_ARRAY);
GL11.glDisableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
} else {
GL11.glBegin(GL11.GL_TRIANGLE_FAN);
GL11.glTexCoord2f(sx, sy);
GL11.glVertex2f(0, 0);
GL11.glTexCoord2f(ex, sy);
GL11.glVertex2f(width,0);
GL11.glTexCoord2f(ex, ey);
GL11.glVertex2f(width, height);
GL11.glTexCoord2f(sx, ey);
GL11.glVertex2f(0, height);
GL11.glEnd();
}
}
And the VBOHandler class, for those interested
public class VBOHandler {
private static int IBOID;
public static void initDefaultIBO() {
IBOID = createVBOID();
short[] indexdata = {0, 1, 2, 3};
ShortBuffer shortBuffer = BufferUtils.createShortBuffer(4);
shortBuffer.put(indexdata);
VBOHandler.bufferElementData(IBOID, shortBuffer);
}
public static int getDefaultIBOID() {
return IBOID;
}
public static int createVBOID() {
if(GLContext.getCapabilities().GL_ARB_vertex_buffer_object) {
return ARBVertexBufferObject.glGenBuffersARB();
}
return 0;
}
public static void bufferData(int id, FloatBuffer buffer) {
if (GLContext.getCapabilities().GL_ARB_vertex_buffer_object) {
ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, id);
ARBVertexBufferObject.glBufferDataARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, buffer, ARBVertexBufferObject.GL_STATIC_DRAW_ARB);
}
}
public static void bufferElementData(int id, ShortBuffer buffer) {
if (GLContext.getCapabilities().GL_ARB_vertex_buffer_object) {
ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ELEMENT_ARRAY_BUFFER_ARB, id);
ARBVertexBufferObject.glBufferDataARB(ARBVertexBufferObject.GL_ELEMENT_ARRAY_BUFFER_ARB, buffer, ARBVertexBufferObject.GL_STATIC_DRAW_ARB);
}
}
public static void bindBuffer(int id) {
ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, id);
}
public static void bindElementBuffer(int id) {
ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ELEMENT_ARRAY_BUFFER_ARB, id);
}
}
The above render-function lies within my Sprite class. It is called by my GameView every frame as so:
public void renderGame() {
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glLoadIdentity();
sprite.render();
}
The GameView is initialized with the following code:
Display.setDisplayMode(new DisplayMode(1024, 768));
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
GL11.glEnable(GL11.GL_BLEND); // enable alpha blending
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glOrtho(x - width/2, x + width/2, y + height / 2, y - height / 2, -1, 1);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
You did not call 'flip' on the FloatBuffers before passing them to OpenGL. You need to call 'flip()' on FloatBuffers before you pass them to OpenGL, or it will not be able to read them. It is worth noting that you cannot read the FloatBuffers after you call 'flip()' yourself.