How should the x, y, z, sizeX, sizeY, sizeZ values be put to the vertices to make a cube?
public static void cube(float x, float y, float z, float sx, float sy, float sz){
glPushMatrix();
{
glTranslatef(x, y, z);
//Just one side of the cube is given due to too much unnecessary code.
glBegin(GL_QUADS);
glVertex3f(-1, -1, 1);
glVertex3f(1, -1, 1);
glVertex3f(1, 1, 1);
glVertex3f(-1, 1, 1);
glEnd();
}
glPopMatrix();
}
Thanks.
Wherever in your code you have e.g. glVertex3f(-1, -1, 1); mulitply them with the corresponding value of sx, sy, sz divided by 2 e.g. glVertex3f(-sx/2, -sy/2, sz/2);
For the position you can issue a glTranslatef(x, y, z) before drawing the cube. If you insist on hardcoding this into the vertices then you should write the above statement as glVertex3f(x - sx/2, y - sy/2, z + sz/2);
Related
This probably sounds weird, but somehow my program just ignores green color
First, I init GL like this: (I don't know, maybe it does matter)
private static void initgl() {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 1280, 720, 0, 1, -1);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_TEXTURE_2D);
}
I'm drawing a square like this:
public static void gameLoop(){
while (!Display.isCloseRequested()){
glClear(GL_COLOR_BUFFER_BIT);
DrawStuff.square(10, 10, 100, 100, new byte[]{127,127,127});
Display.update();
Display.sync(60);
}
}
and in square method I have
public static void square(int x, int y, int w, int h, byte[] rgb) {
glColor3b(rgb[0], rgb[1], rgb[2]);
glBegin(GL_QUADS);
glVertex2i(x, y);
glVertex2i(x + w, y);
glVertex2i(x + w, y + h);
glVertex2i(x,y+h);
glEnd();
}
When I run the program, I see this:
And by the way, color picker says it's #C808C7 . Not even #FF00FF like I expected
what happened to the green color?
why colors are off?
Ok, this answer helped me: How do color and textures work together?
That's not your problem, but it still needs to be done.
What was messing with my colors is glEnable(GL_TEXTURE_2D); To achieve both color and texture filling I have to disable it each time I want to draw something with solid color and then enable again:
public static void square(int x, int y, int w, int h, byte[] rgb) {
glDisable(GL_TEXTURE_2D);
glColor3b(rgb[0], rgb[1], rgb[2]);
glBegin(GL_QUADS);
glVertex2i(x, y);
glVertex2i(x + w, y);
glVertex2i(x + w, y + h);
glVertex2i(x,y+h);
glEnd();
glEnable(GL_TEXTURE_2D);
}
Depending on your case, future reader, you may want to keep it disabled in the first place, only enabling it if you need to add textures.
Volia:
In a middle of developing my game I created a function to rotate a 2d triangle.
But the problem is that when I rotate an object, the rotation is very weird.
If the object's center is at the origin (the (0,0) point) of the axis then it rotates fine, but if I move the object then it rotates in a very weird way that it shouldn't be rotating in.
as you can see here is the code of the function.
public void rotate(float angle){
float x1 = x, y1 = y;
float x2 = x + width, y2 = y;
float x3 = x + width, y3 = y + height;
float x4 = x, y4 = y + height;
// Vertices in object space:
float[] vector1 = {x1, y1, 0f, 1f};
float[] vector2 = {x2, y2, 0f, 1f};
float[] vector3 = {x3, y3, 0f, 1f};
float[] vector4 = {x4, y4, 0f, 1f};
// Vertices in world space:
float[] vector1r = new float[4];
float[] vector2r = new float[4];
float[] vector3r = new float[4];
float[] vector4r = new float[4];
// Calculate the vertices in world space:
Matrix.multiplyMV(vector1r, 0, modelMatrix, 0, vector1, 0);
Matrix.multiplyMV(vector2r, 0, modelMatrix, 0, vector2, 0);
Matrix.multiplyMV(vector3r, 0, modelMatrix, 0, vector3, 0);
Matrix.multiplyMV(vector4r, 0, modelMatrix, 0, vector4, 0);
// Get the middle of the rectangle:
float[] vecMid = {(vector1r[0] + vector3r[0]) / 2,
(vector1r[1] + vector3r[1]) / 2, 0f, 1f};
move(vecMid[0], vecMid[1]); // Move to the origin
Matrix.rotateM(modelMatrix, 0, angle, 0, 0, 1f); // Rotate the object
move(-vecMid[0], -vecMid[1]); // Move back to place
if(LoggerConfig.ON)
Log.d("Middle Vertex", vecMid[0] + ", " + vecMid[1]);
}
The move method:
public void move(float x, float y){
Matrix.translateM(modelMatrix, 0, x, y, 0);
}
Can someone tell me what the problem is?
EDIT: I did some modifications to the code and added the move method.
The Original Problem:
I'm making a 2d game in OpenGL that uses tiles to draw a map. At the moment, each tile is drawn individually on a quad. The code for the tile rendering is:
#Override
public void render() {
if (parentTileSet.getTexture() == null)
return;
float alpha = parentLayer.getOpacity();
if (alpha < 0)
alpha = 0;
glColor4f(1.0f, 1.0f, 1.0f, alpha); //Set alpha to parent layer's alpha
parentTileSet.getTexture().bind(); //Bind texture
float bx = parentTileSet.getTileWidth() / 2; //Half the width
float by = parentTileSet.getTileHeight() / 2; //Half the height
float x = getX(), y = getY();
float z = 0f;
glPushMatrix(); //Save the current view matrix
glTranslatef(x, y, 0f); //Translate to the tile's position
glRotatef(rotate, 0f, 0f, 1f); //Rotate the tile if it has a rotation
if ((flipType & 1) > 0) //Are we flipping horizontally?
glScalef(-1f, 1f, 1f);
if ((flipType & 2) > 0) //Are we flipping vertically?
glScalef(1f, -1f, 1f);
//Draw the tile
glBegin(GL_QUADS);
glTexCoord2f(tex_cords.bottom_left.x, tex_cords.bottom_left.y); //bottom left
glVertex3f(-bx, -by, z);
glTexCoord2f(tex_cords.bottom_right.x, tex_cords.bottom_right.y); //bottom right
glVertex3f(bx, -by, z);
glTexCoord2f(tex_cords.top_right.x, tex_cords.top_right.y); //top right
glVertex3f(bx, by, z);
glTexCoord2f(tex_cords.top_left.x, tex_cords.top_left.y); //top left
glVertex3f(-bx, by, z);
glEnd();
glPopMatrix(); //Reload the view matrix to original state
parentTileSet.getTexture().unbind(); //Unbind the texture
}
And the result looks like the following:
http://i.stack.imgur.com/maIXk.jpg
Which is good. However, the FPS could be better, and this especially becomes an issue when the maps become more detailed. (The FPS drops to about 20).
My Ideal Solution:
Since the tiles will never change position or animate, if I render all the tiles to a texture once, and just draw that texture, then performance will increase!
So, I made a framebuffer using the following class:
public class Framebuffer implements Drawable {
private int fID, tID;
protected int width, height;
public Framebuffer(int width, int height) {
this.width = width;
this.height = height;
}
public void generate() {
fID = glGenFramebuffers();
tID = glGenTextures();
glBindFramebuffer(GL_FRAMEBUFFER, fID);
glBindTexture(GL_TEXTURE_2D, tID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_INT, (ByteBuffer) null);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tID, 0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
throw new RuntimeException("Framebuffer configuration error.");
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
public void begin() {
glPushMatrix();
glPushAttrib(GL_VIEWPORT_BIT);
glBindFramebuffer(GL_FRAMEBUFFER, fID);
glViewport(0, 0, width, height);
}
public void end() {
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glPopMatrix();
glPopAttrib();
}
#Override
public void render() {
float x = 0f;
float y = 0f;
float z = 0f;
float bx = (this.width)/2f;
float by = (this.height)/2f;
glPushMatrix();
glBindTexture(GL_TEXTURE_2D, tID);
glBegin(GL_QUADS);
glTexCoord2f(0f, 0f); //bottom left
glVertex3f(x - bx, y - by, z);
glTexCoord2f(1f, 0f); //bottom right
glVertex3f(x + bx, y - by, z);
glTexCoord2f(1f, 1f); //top right
glVertex3f(x + bx, y + by, z);
glTexCoord2f(0f, 1f); //top left
glVertex3f(x - bx, y + by, z);
glEnd();
glBindTexture(GL_TEXTURE_2D, 0);
glPopMatrix();
}
And then use the following code to generate the framebuffer, and render the tiles to the texture:
System.out.println("Attempting to generate frame buffer..");
try {
Framebuffer frame = new Framebuffer(tiledData.getPixelWidth(), tiledData.getPixelHeight());
frame.generate();
frame.begin();
glScalef(0.5f, 0.5f, 1f); //The game is scaled up by 2, so I'm just unscalling here.
Iterator<Drawable> drawableIterator = getSortedDrawables();
while (drawableIterator.hasNext()) {
Drawable d = drawableIterator.next();
if (d instanceof TileObject) {
TileObject t = (TileObject)d;
if (t.isGroundLayer() && !t.isParallaxLayer() && !t.isAnimated()) {
t.render(); //This render method is the one from above
drawableIterator.remove();
}
}
}
frame.end();
System.out.println("Success!");
addDrawable(frame);
} catch (RuntimeException e) {
System.out.println("Framebuffers are not supported!");
}
However, the output is this:
http://puu.sh/8Eemy.jpg
Which is not what I expected to happen. I tried scaling it, moving it, and all sorts of things but I can never get it exactly right.
My Question
What am I doing wrong? Is there another way to go about this? Am I missing something?
UPDATE
Thanks to the comments, I've got it to render correctly!
I changed the framebuffer class to be the following:
private int fID, tID;
protected int width, height;
public Framebuffer(int width, int height) {
this.width = width;
this.height = height;
}
public void generate() {
fID = glGenFramebuffers();
tID = glGenTextures();
glBindFramebuffer(GL_FRAMEBUFFER, fID);
glBindTexture(GL_TEXTURE_2D, tID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_INT, (ByteBuffer) null);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tID, 0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
throw new RuntimeException("Framebuffer configuration error.");
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
public void begin() {
glBindFramebuffer(GL_FRAMEBUFFER, fID);
glPushAttrib(GL_VIEWPORT_BIT);
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0, width, 0, height, -1, 1);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
}
public void end() {
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glPopAttrib();
}
#Override
public void render() {
float x = this.width / 2f;
float y = this.height / 2f;
float z = 0f;
float bx = (this.width)/2f;
float by = (this.height)/2f;
glPushMatrix();
glBindTexture(GL_TEXTURE_2D, tID);
glBegin(GL_QUADS);
glTexCoord2f(0f, 0f); //bottom left
glVertex3f(x - bx, y - by, z);
glTexCoord2f(1f, 0f); //bottom right
glVertex3f(x + bx, y - by, z);
glTexCoord2f(1f, 1f); //top right
glVertex3f(x + bx, y + by, z);
glTexCoord2f(0f, 1f); //top left
glVertex3f(x - bx, y + by, z);
glEnd();
glBindTexture(GL_TEXTURE_2D, 0);
glPopMatrix();
}
The points of interest here is the begin() and end() method, where I setup a new projection matrix and save the old one, then restore it in the end() method.
I am doing something with JOGL libraries (forced to) and I can't figure out how to offset the center zero coordinates. I would like to offset them to the bottom of my viewport, in the method
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height)
but I can't google any way to translate int height into any meaningfull offset float coordinates.
edit:
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL_PROJECTION);
gl.glLoadIdentity();
glu.gluPerspective(45.0, width / (float) height, 0.1, 100.0);
gl.glMatrixMode(GL_MODELVIEW);
gl.glLoadIdentity();
Solved using
glu.gluLookAt(0, 0, 1, 0, 0.42, 0, 0, 1, 0);
Didn't realize the offset wasn't relative.
I am working on a infinite world generated with Perlin Noise, Java and LWJGL. But I am having a problem, it is kinda hard to explain, so I made a video: http://youtu.be/D_NUBJZ_5Kw Obviously the problem is the black spaces in between all the pieces of ground.
I already tried making all the values doubles instead of floats, but that didn't fix it.
Here is a piece of code I am using:
float height2, height = (float)getHeight(x, y);
height2 = (float) ((getHeight(x-1, y+1) + height) / 2);
vertexhelper.addVertexColorAndTexture(x, height2, y+1, r, g, b, a, 0f, 1f);
height2 = (float) ((getHeight(x+1, y+1) + height) / 2);
vertexhelper.addVertexColorAndTexture(x+1, height2, y+1, r, g, b, a, 1f, 1f);
height2 = (float) ((getHeight(x+1, y-1) + height) / 2);
vertexhelper.addVertexColorAndTexture(x+1, height2, y, r, g, b, a, 1f, 0f);
height2 = (float) ((getHeight(x-1, y-1) + height) / 2);
vertexhelper.addVertexColorAndTexture(x, height2, y, r, g, b, a, 0f, 0f);
I loop through this at the initialization of a chunk with x->16 and y->16. vertexhelper is a class I made that just puts everything in a array.
(I am using floats here, but that's after doing the maths, so that shouldn't be a problem)
I had to take 4 places on the heightmap in account instead of 2. So instead of
height2 = (float) ((getHeight(x-1, y-1) + height) / 2);
I had to use
height2 = (float) ((getHeight(x, y-1) + getHeight(x-1, y) + getHeight(x-1, y-1) + height) / 4);
That fixed it.