I am declaring the GLfloat vertices[][3], GLfloat normals[][3] and GLfloat colors[][3] and after I declare the structs for the cube and board according to the following code. I want the cubes to have a gap or 0.1% of the cube size, so scale them by a factor of 0.99. What is failing is to see that gap.
typedef struct cube * Cube;
struct cube {
float x, y, z;
float scale;
};
Cube cube; // cube
Cube *board;
void drawBoard()
{
// Initialize cube and board
cube = (Cube)malloc(sizeof(struct cube));
cube->x = 0.0;
cube->y = 0.0;
cube->z = 0.0;
cube->scale = 1;
board = (Cube*)malloc(sizeof(Cube)*64);
for(int i=0; i<64; i++) {
board[i] = (Cube)malloc(sizeof(struct cube));
board[i]->x = 0.0 + 0.1*(i%8);
board[i]->y = 0.0 - 0.1*(i/8);
board[i]->z = 0.0;
board[i]->scale = 0.99;
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glTranslatef(cube->x, cube->y, cube->z);
//glScalef(cube->scale, cube->scale, cube->scale);
// Draw board of cubes
for(int i=0; i<64; i++) {
glPushMatrix();
glTranslatef(board[i]->x, board[i]->y, board[i]->z);
glScalef(board[i]->scale, board[i]->scale, board[i]->scale);
drawCube();
glEnd();
glPopMatrix();
}
glPopMatrix();
glFlush();
}
I am expecting to see a board size columns X lines of 3d cubes considering the cubes have a size = 1, with a gap between them of 0.1% of their size.The board is drawned but the cubes seem to be all placed side by side with no gaps.
So you are drawing a bunch of cubes on a grid, and the size of the cube (if you imagine measure from one side to the other side with a ruler) is 0.99 (the actual cube size is 1.0 and you scaled it by 0.99), and the distance between the middle of the first cube and the middle of the second cube is only 0.1.
That means the cubes are overlapping each other by quite a lot. so of course there are no spaces between them. If you want to put cubes on a 0.1 grid with gaps between them, obviously each cube has to be smaller than 0.1.
If you'll pardon the lazy drawing, you think your cubes are like this:
but they are actually more like this:
because the gap between the cubes is way smaller than the size of each cube.
Related
I am having trouble to make the camera rotate around my object. I am going to try to express myself as good as i can.
The objective is that when i load a new object and select it, (selecting it means that _selected_object points to the new object), the active camera points only to the center of the object(when analisis mode is activated), so the rotations and translation( translations just in the Z axis) are made around this object.
This is what i am trying right now:
_selected_camera->at.x=_selected_object->mtptr->M[3];
_selected_camera->at.y=_selected_object->mtptr->M[7];
_selected_camera->at.z=_selected_object->mtptr->M[11];
This code happens when the analisis mode (camera pointing and moving towards object) is activated. But when i move the object, the camera points nowhere or where it was initially pointing.
at.x from selected camera is the point towards the camera is looking. mtptr is the 4x4 matrix position of the object (in which object transformations are made), where last column has the center of the object.
If you're using legacy OpenGL, use gluLookAt.
Otherwise (pseudo code):
mat4 lookAt(vec3 eye, vec3 target, vec3 up)
{
//calculate axes based on the provided parameters
//cross product gives us the perpendicular vector
vec3 z = eye - target;
vec3 x = cross(up, z);
vec3 y = cross(z, x);
//normalize to make unit vectors
normalize(x);
normalize(y);
normalize(z);
//translation vector
//based on the angle between the eye vector (camera position) and the axes
//hint: angle = dot(a, b) -> see: https://en.wikipedia.org/wiki/Dot_product
vec3 t = {
-dot(eye, x),
-dot(eye, y),
-dot(eye, z)
};
return { //a combined scale, skew, rotation and translation matrix
x[0], x[1], x[2], t[0],
y[0], y[1], y[2], t[1],
z[0], z[1], z[2], t[2],
0, 0, 0, 1
};
}
Multiply the resulting (view) matrix with a projection matrix (ortho, perspective).
I'm trying to rotate a 2D pixel matrix, but nothing actually happens.
my origin is a stored bitmap[w x h x 3].
why isn't the shown image being rotated?
Here's the display function:
void display()
{
uint32_t i = 0,j = 0,k = 0;
unsigned char pixels[WINDOW_WIDTH * WINDOW_HEIGHT * 3];
memset(pixels, 0, sizeof(pixels));
for(j = bitmap_h -1; j > 0; j--) {
for(i = 0; i < bitmap_w; i++) {
pixels[k++]=bitmap[j][i].r;
pixels[k++]=bitmap[j][i].g;
pixels[k++]=bitmap[j][i].b;
}
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glRotatef(90,0,0,1);
glDrawPixels(g_img.descriptor.size_w, g_img.descriptor.size_h, GL_RGB, GL_UNSIGNED_BYTE, &pixels);
glutSwapBuffers();
}
First and foremost glDrawPixels should not be used. The problem you have is one of the reasons. The convoluted rules by which glDrawPixels operate are too vast to outline here, let's just say, that there's a so called "raster position" in your window, at which glDrawPixels will place the lower left corner of the image it draws. No transformation whatsoever will be applied to the image.
However when setting the raster position, that's when transformations get applied. And should, for whatever reason, the raster position lie outside the visible window nothing will get drawn at all.
Solution: Don't use glDrawPixels. Don't use glDrawPixels. DON'T USE glDrawPixels. I repeat DON'T USE glDrawPixels. It's best you completely forget that this function actually exists in legacy OpenGL.
Use a textured quad instead. That will also transform properly.
I did something similar. I'm creating a 3D space shooter game using OpenGL/C++. For one of my levels, I have a bunch of asteroids/rocks in the background each rotating and moving at a random speed.
I did this by taking the asteroid bitmap image and creating a texture. Then I applied the texture to a square (glBegin(GL_QUADS)). Each time I draw the square, I multiply each of the vertex coordinates (glVertex3f(x, y, z)) with a rotation matrix.
|cos0 -sin0|
|sin0 cos0 |
0 is the theta angle. I store this angle as part of my Asteroid class. each iteration I increment it by a value, depending on how fast I want the asteroid to spin. It works great.
I'm not sure if my Perlin Noise generator is functioning properly, the noise it generates looks very different from the images I see online. Mine looks too homogeneous (these are three different images):
Whereas what I usually see is something like:
My code is basically:
/* Get the coord of the top-left gradient of the grid (y, x) falls in */
int j = floor(x);
int i = floor(y);
/* Get the distance (y, x) is from it */
double dx = x-j;
double dy = y-i;
/* Influence of (g)radient(i)(j) (starting at the top-left one) */
double g00 = dot(grad(hashes, hsize, grads, i, j), dy, dx);
double g01 = dot(grad(hashes, hsize, grads, i, j+1), dy, dx-1);
double g10 = dot(grad(hashes, hsize, grads, i+1, j), dy-1, dx);
double g11 = dot(grad(hashes, hsize, grads, i+1, j+1), dy-1, dx-1);
/* Interpolate the influences using the blending function */
/* Linear interpol the top 2 */
double lt = lerp(g00, g01, fade(dx));
/* Linear interpol the bottom 2 */
double lb = lerp(g10, g11, fade(dx));
/* Linear interpol lb lt, completing the bilienear interpol */
return lerp(lt, lb, fade(dy));
Complete code. It's based mainly on this tutorial. I'm using this script to draw the csv file.
I understand the basics, but after reading several "tutorials" that usually contradict each other and the "reference implementation" which is not very readable I have a few doubts. The (x, y) points being interpolated should be in what interval? As I understand it, it should be [0, GRID_SIZE-1] (e.g. [0, 255] if using a pre-computed table with 256 random values). However, my code only results in reasonably good looking images when (x, y) is mapped to [0, 1], and I see some implementations online that map it to [0, 255] no matter the grid size. I'm also unsure if I'm picking the gradients correctly from the table.
You normalize your pixel coordinates to the whole image. You should normalize it to the size of your simplex grid.
So instead of your code for the inner loop:
double x = j/(double)w;
double y = i/(double)h;
do:
double x = j / gridsize;
double y = i / gridsize;
where the grid size is an additional parameter, for example:
double gridsize = 32.0;
(It should probably be chosen to fit evenly into the image dimensions.)
I've got an array of strings that I'd like to draw as a giant spiral. I only have a very, very rough idea of where to begin. First, I will probably need to break the strings into an array of individual characters? Next, I will probably need to apply the following geometry in order to generate the spiral shape?
float r = 0;
float theta = 0;
void setup() {
size(200,200);
background(255);
}
void draw() {
float x = r * cos(theta);
float y = r * sin(theta);
noStroke();
fill(0);
ellipse(x+width/2, y+height/2, 6, 6);
theta += 0.01;
r += 0.05;
}
However, I don't know how to step through my array of characters in order to draw them in a spiral-like format. I apologize for the lack of clarity. Any suggestions would be awesome! I'm very new to all of this (clearly).
Your code for creating the spiral is a good idea. One way to create rotated text would be using rotate(), combined with text(). You would have a for loop, iterate through your character array, increment the radius, and draw your text that way. Note that rotate() has a cumulative effect. Something like:
String str = "asdflkkjsahfdlkadshflkahdslkfajsdf";
float radius = 0;
//so we are rotating around the center, rather than (0,0):
translate(width/2, height/2);
for (int i = 0; i < str.length(); i++) {
radius += 2;
// taken out because of non-constant spacing at large radius:
//rotate(0.5);
// this should give constant spacing, no matter the radius
// change 10 to some other number for a different spacing.
rotate(10/radius);
// drawing at (0,radius) because we're drawing onto a rotated canvas
text(str.charAt(i), 0, radius);
}
You may want to have the angle change be a function of radius, because at large radii, the letters are spaced very far apart. One way to do this would be using the equation s = rθ, where s is the arclength (in this case, distance between letters), r is radius, and θ is the angle change. If you want a constant distance between letters, regardless of radius, then θ would have to be proportional to 1/r. And of course, you can tweak the hard-coded values to your liking.
Also: the rotate() and translate() methods are undone at the end of draw(), so if you aren't doing anything after this code, then it's okay to leave it as is. If you do want to draw more stuff after, then you'll have to undo the rotation and translation manually before you draw anything else.
Edit: I just realized that I assumed you wanted the letters to be rotated as well, and not just positioned in a spiral but still oriented normally. In that case, you could use your existing code and replace the ellipse(...) with text(str.charAt(...)...), with appropriate parameters of course.
I was thinking of creating a 2x2 array with randomly generated values which then be drawn using glVertex3i, for example:
glBegin(GL_POLYGON);
int x = 5;
int z = 5;
for (int i=0; i<width; i++)
{
for (int j=0; j<height; j++)
{
glVertex3i(x, heightmap[i][j], z);
}
x -= 0.5;
z -= 0.5;
}
glEnd();
The only problem I'm having is that, the map isn't drawn on the z dimension I think, because all I get is 1 side essentially.
What might be wrong? Obviously the algorithm is basic for now, but its just a starting point.
What might be wrong?
Let's start here:
glBegin(GL_POLYGON);
A polygon is required to be planar. All of the vertices must lie in a single plane. If they don't, then OpenGL is not responsible for how it gets rendered. You cannot draw a heightmap as a single polygon and expect to get reasonable results. You must draw triangles, either with a series of GL_TRIANGLE_STRIPs or with GL_TRIANGLES.
Then, there's what Christian said.
Maybe you mean
float x = 5.0f;
for (int i=0; i<width; i++)
{
float z = 5.0f;
for (int j=0; j<height; j++)
{
glVertex3f(x, heightmap[i][j], z);
z -= 0.5f;
}
x -= 0.5f;
}
Or with x and z switched, depends on your convention. But first, don't subtract 0.5 from an int, it will draw the same vertex twice. And second, one variable needs to run in the inner loop, the other in the outer loop. Or did I misundertand the question?
And are you sure you want the whole heightmap to make up a single polygon? Maybe I really misunderstood the question?