I have a several quads which are successfully being displayed on the screen, however when I try to set the colour of one of them it sets the color of all of them.
GL11.glColor3f(red,green,blue);
xh = getXsize() / 2;
yh = getYsize() / 2;
GL11.glPushMatrix();
GL11.glTranslated(x, y, 0);
GL11.glTranslatef(10.0f, 10.5f, -0.0f);
GL11.glRotated(rotate, 0.0f, 0.0f, -1.0f);
GL11.glTranslatef(-10.0f, -10.5f, 0.0f);
GL11.glTranslated(-x, -y, 0);
GL11.glBegin(GL11.GL_QUADS);
GL11.glVertex2d(x - xh, y - yh);
GL11.glVertex2d(x - xh, y + yh);
GL11.glVertex2d(x + xh, y + yh);
GL11.glVertex2d(x + xh, y - yh);
GL11.glEnd();
GL11.glPopMatrix();
As far as I see, only one quad is drawn in the code you have posted. Anyways, when you call GL11.glColor3f(red,green,blue) it will be applied to all following quads you draw after calling it. Basically, if you want different color quads, you need to call the function with different values, every time before drawing new quad.
You should give a look on the following to this resource (it's not JWJGL, but OpenGL) in the section called : Specifying a Color and a Shading Model, which explains bit better how the color is being applied to the simple shapes.
Related
Does anyone know whether libGDX has a method for scrolling/shifting an image/texture within itself?
To explain; I would like to be able to scroll the contents (pixels) of an image, either vertically or horizontally within its own region. For example, if an image is shifted 1 pixel to the right, all pixels move 1 to the right and those on the right-most-edge are wrapped to the left-most-edge. The image size does not change, only the positioning of the pixels within it change.
I have mainly been working with the Sprite class, it can do a lot (scale, rotate, etc) but shift/scroll as I need it, isn't there.
Before writting the method myself, I thought I'd ask here...
The following worked for me, this was provided by Kush:
float delta = 0f;
// In the Actors act method
delta += Gdx.graphics.getDeltaTime();
// Horizontal
batch.draw(texture, 0, 0, width, height, 0 + delta * 10, 1, 1 + delta * 10, 0);
// Vertical
batch.draw(texture, 0, 0, width, height, 1, 0 + delta * 10, 0, 1 + delta * 10);
You won't need Sprite for this, draw directly Texture using batch. For wrapping first set
Texture texture = new Texture("example.png");
texture.setWrap(TextureWrap.Repeat, TextureWrap.Repeat);
then draw using uv
batch.draw(texture, x, y, width, height, u, v, u2, v2);
or any other method that suits you in SpriteBatch.
I'm trying to rotate a rectangular Slick2d image with pixel size 666 x 333 using LWJGL. I was able to rotate a square image with pixel size 666 x 666 around its center, but the rectangular image does distort during the rotation and this is my problem.
Here is the image I use for testing purposes:
http://i.stack.imgur.com/0bjr5.jpg
The left window shows the image before the rotation, the right window shows the image how it looks when I rotate it 90 degrees, it's distorted:
http://i.stack.imgur.com/FGcNB.jpg
Here is my source code snippet for the rotation:
float x = 0.335f;
float y = 0.335f;
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glTranslatef(x, y, 0f);
glRotatef(angle, 0f, 0f, 1f);
glTranslatef(-x, -y, 0f);
glMatrixMode(GL_MODELVIEW);
You may wonder why I don't use the function “setRotation” or “rotate” of a Slick2d Image. The reason I don't use this does not matter here, but I simply can't use it in my real project and furthermore I want to do it with gl.
It's the first time ever I touch LWJGL and Slick2d and I need it only for a small part of my project. If you know how to rotate the image like above without the distortion, please help me. Thank you.
The problem could be because:
You are using Slick-2D. glRotatef and glTranslatef require a Z coordinate. This could confuse slick 2D. Also what is your angle variable? glTranslatef translates the position of a quad. With lwjgl 3D this would be used to translate the object. glRotatef uses vector rotation. Try researching vector rotation.
Here is a simple pseudocode formula:
Calculate the sine and cosine of the angle once. Dim cosTheta As Double, sinTheta As Single cosTheta = Cos(DegreesToRadians(Angle)) sinTheta = Sin(DegreesToRadians(Angle)) ' Get the disance between the center and the point. Dim dblDistanceX As Double, dblDistanceY As Double dblDistanceX = (PointX - CenterX) dblDistanceY = (PointY - CenterY) ' Set the default position. ReturnX = CenterX ReturnY = CenterY 'Update with the Y offset ReturnX = (ReturnX + dblDistanceY * sinTheta) ReturnY = (ReturnY + dblDistanceY * cosTheta) 'Update with the X offset ReturnX = (ReturnX + dblDistanceX * cosTheta) ReturnY = (ReturnY - dblDistanceX * sinTheta)
90 degree rotation is extremely simple. Just rotate the quad and rebind texture. If you can't do this, then make a 90 degree rotated texture. Just ask if you want another answer with my 90 degree rotation code. I tried to explain how you could use vectors for 360 degree rotation.
I wrote some code to get a plain 2d box to face the mouse. It rotated just fine around its center, and everything was working great, but when i put a texture on the box, it did not rotate around the center anymore.
The code:
float imgWidth = texture.getImageWidth()*scale;
float imgHeight = texture.getImageHeight()*scale;
glLoadIdentity();
texture.bind();
glTranslatef(x, y, 0);
glRotated(rotation - 90, 0, 0, 360);
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex2f(-imgWidth, -imgHeight);
glTexCoord2f(1, 0);
glVertex2f(imgWidth, -imgHeight);
glTexCoord2f(1,1);
glVertex2f(imgWidth, imgHeight);
glTexCoord2f(0, 1);
glVertex2f(-imgWidth, imgHeight);
glEnd();
The answer is simple but with a complicated background that has to be understood.
OpenGL always rotate something not around its center but takes as center the point (0;0).
This can be an issue because if you translate your object somewhere and then your rotate it, it will rotate not on its center but around the (0;0) point (origin) creating a big rotation, I will say as a planet around the Sun.
Also OpenGL works with matrix, that with very barbaric simplification means that the operation are executed bottom to top.
// store the current model matrix
GL11.glPushMatrix();
// bind to the appropriate texture for this image
this.texture.bind();
// translate to the right location and prepare to draw
GL11.glColor3f(1, 1, 1);
GL11.glTranslated(x + (this.texture.getImageWidth() / 2), y + (this.texture.getImageHeight() / 2), 0);
GL11.glRotated(this.angle, 0, 0, 1);
GL11.glTranslated(-this.texture.getImageWidth() / 2, -this.texture.getImageHeight() / 2, 0);
// draw a quad textured to match the sprite
GL11.glBegin(GL11.GL_QUADS);
{
GL11.glTexCoord2f(0, 0);
GL11.glVertex2f(0, 0);
GL11.glTexCoord2f(0, this.texture.getHeight());
GL11.glVertex2f(0, this.texture.getImageHeight());
GL11.glTexCoord2f(this.texture.getWidth(), this.texture.getHeight());
GL11.glVertex2f(this.texture.getImageWidth(), this.texture.getImageHeight());
GL11.glTexCoord2f(this.texture.getWidth(), 0);
GL11.glVertex2f(this.texture.getImageWidth(), 0);
}
GL11.glEnd();
// restore the model view matrix to prevent contamination
GL11.glPopMatrix();
This means that first I am moving the texture to have its center positioned at (0;0) that means translating it backward half the dimensions.
Then I rotate it, and this is the crucial point, because you are using a strange way to rotate it, maybe the problem it's here, take a look to the javadoc:
SPECIFICATION
void glRotated( GLdouble angle,<br>
GLdouble x,<br>
GLdouble y,<br>
GLdouble z )<br>
void glRotatef( GLfloat angle,<br>
GLfloat x,<br>
GLfloat y,<br>
GLfloat z )<br>
PARAMETERS<br>
angle Specifies the angle of rotation, in degrees.
x, y, z<br>
Specify the x, y, and z coordinates of a vector, respectively.
DESCRIPTION<br>
glRotate produces a rotation of angle degrees around the<br>
vector (x,y,z).
First of all all x,y,z values should be between 0 and 1, if you want to rotate a 2d image then you should use the z axis, so the third param will be 1 that mean that you are rotating your image around the unit vector z.
The angle should be in degree and can be either positive or negative.
Try to change your code according to the documentation and you will have your problem solved.
Also with your quad you are drawing a 2x scaled quad, you are starting from -imageWidth to +imageWidth that means 2 times the width...
So, I'm new to OpenGL and trying to create a 2D Multiplayer game, I know how to do all of the networking, although the graphics portion is honestly kicking my buttox.
I have tried looking at NiftyGUI aswell as TWL as they have been recommended a-lot, although I can't seem to get a grasp of them as there aren't very many tutorials and no videos to help explain what's going on, not to mention the OpenGL Documentary page is just horribly laid out.
I've attemped drawing a black rectangle, which I was going to go ahead and outline in white somehow and making that a temporary textbox, by drawing white font onto it, although I don't even know how to draw font. These are just a few of the things I'm strugling with that I can't find and I'm aware that I'm going to have to use some libraries, so I'll name the ones I have implemented currently.
LWJGL
Slick2D
I don't have any others currently, besides for TWL but I can't figure out how to use it for the life of me.
Here's the code that I made myself while trying to get a small black rectangle going
void drawTextBox(int fromLeft, int fromTop, int width, int height) {
glColor3f(1.0f, 1.0f, 1.0f);
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex2i(fromLeft, fromTop); // Upper Left
glTexCoord2f(1, 0);
glVertex2i(fromLeft - width, fromTop); // Uppright
glTexCoord2f(1, 1);
glVertex2i(fromLeft - width, fromTop + height); // Bottom right
glTexCoord2f(0, 1);
glVertex2i(fromLeft, fromTop + height); // bottom left
glEnd();
}
This is working correctly, all but one part... It's drawing the last texture that I have loaded, even though I'm not binding it anywhere in the program, because I've made sure of it. Then it's scaling it to fit into the dimensions of the text-box.
Could someone help me resolve this error and direct me to where I can learn how to set the opacity of quads as-well as draw some text?
Try binding the texture you want right before calling the function. Without knowing how you've "made sure" that the other texture is not being bound, that's all I can say. Also, for changing opacity simply use one of GL11.glColor4_ functions; the last parameter is the alpha (opacity) of the color.
void drawTextBox(int fromLeft, int fromTop, int width, int height) {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glColor4f(1.0f, 1.0f, 1.0f, <B>0.5f</B>);
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex2i(fromLeft, fromTop); // Upper Left
glTexCoord2f(1, 0);
glVertex2i(fromLeft - width, fromTop); // Uppright
glTexCoord2f(1, 1);
glVertex2i(fromLeft - width, fromTop + height); // Bottom right
glTexCoord2f(0, 1);
glVertex2i(fromLeft, fromTop + height); // bottom left
glEnd();
glDisable(GL_BLEND);
}
This block of code allows you to draw a white rectangle with %50 opacity.
Take a look at the BOLDED part (0.5f). This float number defines the opacity of your rectangle. The bigger this number is (0.0f~1.0f), the more the opacity of the rectangle is.
The following code produces the image that follows. The image I am using for the background is 640 x 480, as is the displayMode. The texture background is a .bmp and is loaded with the Slick texture loader. I am confuse to why it is not filling the Quad and why it is reflected.
EDIT: The background of my OpenGL scene is pink, the black you see is from the Quad created. The background image is the green block with a 2px light blue border with "test" plastered on it.
private void renderBackground(){
float w = displayMode.getHeight()/2;
float h = displayMode.getWidth()/2;
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glPushMatrix();
GL11.glLoadIdentity();
GLU.gluOrtho2D(-w, w, -h, h);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glPushMatrix();
GL11.glLoadIdentity();
GL11.glDisable(GL11.GL_DEPTH_TEST);
if(useTextures)background.bind();
GL11.glBegin(GL11.GL_QUADS);
GL11.glTexCoord2f(0.0f, 0.0f);
GL11.glVertex2f(-w,-h);
GL11.glTexCoord2f(1.0f, 0.0f);
GL11.glVertex2f(w,-h);
GL11.glTexCoord2f(1.0f, 1.0f);
GL11.glVertex2f(w, h);
GL11.glTexCoord2f(0.0f, 1.0f);
GL11.glVertex2f(-w, h);
GL11.glEnd();
GL11.glEnable(GL11.GL_DEPTH_TEST);
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glPopMatrix();
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glPopMatrix();
}
Now when I add GL11.glTranslatef(20.0f, 20.0f, 0.0f); you will notice that the pink appears, which is the colour created int my "initGL" method:
GL11.glClearColor(1.0f, 0.75f, 0.796f, 0.0f);
My GL_PROJECTION contains the following before pushing it, my GL_MODELVIEW is unmodified when renderBackground() is called.
GL11.glMatrixMode(GL11.GL_PROJECTION); // Select The Projection Matrix
GL11.glLoadIdentity(); // Reset The Projection Matrix
// Calculate The Aspect Ratio Of The Window
GLU.gluPerspective(45.0f, (float) displayMode.getWidth() / (float) displayMode.getHeight(), 0.1f, 25.0f);
//position camera
GLU.gluLookAt(5.0f, 3.0f, -5.0f, 0.0f, 0.0f, -10.0f, 0.0f, 1.0f, 0.0f);
GL11.glMatrixMode(GL11.GL_MODELVIEW); // Select The Modelview Matrix
I need more information to determine the problem, but here is a list with some possibilities.
1) You are using an older video card, which does not support texture non-power of 2, since you are using a library to load the texture, maybe it is detecting it, creating a power of two image, and filling it with black.
2) You (or some library you are using) changed the matrix of the texture matrix stack, and it is changing the texture coordinates.
3) You are doing something wrong when you load the texture (or call the library to do so).
The first thing I would check is if your video card supports texture non-power of 2 extension. You can check it at runtime, see how to detect if openGL/card supports non power of 2?
What I see first, is that you compute
float w = displayMode.getHeight()/2;
float h = displayMode.getWidth()/2;
switched?
Second, the texture could be flipped because the loader flipped it (when I remember right this happened to me, too especially with BMPs).