precise texture mapping for polygon voxelization [closed] - c++

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I am recently implement a voxel cone tracing algorithm, the first step is to voxelize polygons...
I am using sparse octree to convert the polygon, everything was fine except for texture mapping
mipmap=6 (64x64x64)
// We find its smallest AABB
AABB aabb = FindAABB(in);
// better aabb with same width, height and depth
AABB betterAABB = FixAABB(aabb);
// Create Octree and marked the grids that are touched by triangles in the mesh
// dfunc is a callable object which return true when triangle and grid are overlapped
// cb is a callable object, it is called when octree reaches its leaf..
Octree<uint8> tree(betterAABB, mipmap);
for(auto &f: in.faces)
tree.findTouchedLeaves(f, dfunc, cb);
Callback function...
struct Callback
{
void operator()(OctreeNode<uint8> *node, const Face &obj)
{
// Check if the node is already marked.
if(!node->data.value)
{
const glm::vec3 &center=node->aabb.getCenter();
out.push_back(center);
// Problem here!! how to calculate precise uv for texture mapping
color.push_back(text->getPixel((obj.o.texCoord+obj.a.texCoord+obj.b.texCoord)/3.0f));
}
node->data.value=1;
}
std::vector<glm::vec3> out;
std::vector<glm::vec4> color;
const ImageTexture *text;
} cb;
as you can see... I directly average three UVs of o,a,b.(terrible right?)
It is more imprecise when a triangle is larger than a grid.
Should I need to use rasterize-based algorithm?
My question is: How to precisely coloring a grid?

Related

What is the maximum color value in GLSL unsinged int? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
In my fragment shader, I need to use uvec4.
My shader:
layout (location = 0) out uvec4 final_color;
void main(void) {
final_color.r = 0;
final_color.g = 4294967295;
final_color.b = 0;
return;
}
I think, this will be green because unsigned_int max is 4294967295. (2^32-1) but it is just black.
I tried singed int max, 2147483647, it's black too. but 2137483648 works. Where is the boundary?
I want know max value, like 255(8bit) or 1.0f(float, vec4).
my program draw result to window directly. I need to see it.
Well, you can't. A uvec4 contains unsigned, 32-bit integers. That output can only be written to an image that uses an unsigned integer image format. Note that this is different from a normalized integer image format.
You cannot create a default framebuffer that contains non-normalized integers, only floats and normalized integers. So you can't "see it".
As such, that value is not a "color"; it's just data stored in a texture. What it means is entirely up to how you will eventually use the value in that texture to get something displayable.

Programming a specific 3d (star-like) model in OpenGL? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
How can I create the following model:
by starting from the first drawing. Could it be programmed in OpenGL entirely or should I use other software like 3d Studio Max or Unity? Are there some specific algorithms that should be used?
Yes this can be done in C++/OpenGL
create random curves emitting from center
simple 3D quadratic polynomial curve will fit the bill.
convert the curves to cones
simply interpolate points along each curve and use it as a center for the cone slice. The direction is set by the previous or next point along the curve. Interpolate the cone slices and add their points to some point list. See:
Smoothly connecting circle centers
create faces
simply connect the computed points to form the cones using any primitive ... I would suggest GL_QUADs...
core
if you want to add also the core (nuclei?) it can be done a s a sphere with some noise added to its surface and probably some filtering to smooth it a bit...
Here simple curve generation C++ example:
List<double> pnt;
void spicule_init()
{
double t,tt,x,y,z;
double a0[3],a1[3],a2[3];
int ix0,ix,i,j;
Randomize();
for (i=0;i<20;i++) // cones
{
// random quadratic 3D curve coeff
for (j=0;j<3;j++)
{
a0[j]=0.0; // center (0,0,0)
a1[j]=2.0*(Random()-0.5); // main direction
a2[j]=1.0*(Random()-0.5); // curvature
}
// curve interpolation
ix0=pnt.num;
for (t=0.0;t<=1.0;t+=0.04)
for (tt=t*t,j=0;j<3;j++)
pnt.add(a0[j]+(a1[j]*t)+(a2[j]*tt));
}
}
Preview of the generated points:
[Edit1] When added the cones,normals and faces it looks like this:
Its far from perfect but I think is a good start point. Just tweak the radius r and the curve coefficients a1[],a2[] to achieve desired shape ... and may be add the core and or check for self intersections too, I am too lazy to do that...
Here the updated C++/GL code:
//---------------------------------------------------------------------------
List<double> pnt,nor; // points, normals
List<int> fac; // QUAD faces
//---------------------------------------------------------------------------
void Circle3D(List<double> &pnt,List<double> &nor,double *p0,double *n0,double r,int N)
{
int i;
double a,da=divide(pi2,N),p[3],dp[3],x[3],y[3];
vector_ld(x,1.0,0.0,0.0); if (fabs(vector_mul(x,n0)>0.7)) vector_ld(x,0.0,1.0,0.0);
vector_mul(x,x,n0); vector_one(x,x);
vector_mul(y,x,n0); vector_one(y,y);
for (a=0.0,i=0;i<N;i++,a+=da)
{
vector_mul( p,x,cos(a));
vector_mul(dp,y,sin(a));
vector_add(p,p,dp); nor.add(p[0]); nor.add(p[1]); nor.add(p[2]);
vector_mul(p,p,r);
vector_add(p,p,p0); pnt.add(p[0]); pnt.add(p[1]); pnt.add(p[2]);
}
}
//---------------------------------------------------------------------------
void spicule_init() // generate random spicule mesh
{
const int N=36; // points/circle
const int N3=3*N;
double t,tt,x,y,z,r;
double a0[3],a1[3],a2[3];
double p[3],n[3];
int e,i,j,i00,i01,i10,i11;
Randomize();
pnt.num=0; nor.num=0; fac.num=0;
for (i=0;i<20;i++) // cones
{
// random quadratic 3D curve coeff
for (j=0;j<3;j++)
{
a0[j]=0.0; // center (0,0,0)
a1[j]=2.0*(Random()-0.5); // main direction and size
a2[j]=1.0*(Random()-0.5); // curvature
}
// curve interpolation
vector_ld(n,0.0,0.0,0.0);
for (e=0,t=0.05;t<=1.0;t+=0.05)
{
// points,normals
for (tt=t*t,j=0;j<3;j++) p[j]=a0[j]+(a1[j]*t)+(a2[j]*tt);
r=0.15*(1.0-pow(t,0.1)); // radius is shrinking with t
vector_sub(n,p,n); // normal is p(t)-p(t-dt)
Circle3D(pnt,nor,p,n,r,N); // add circle to pnt (N points)
vector_copy(n,p); // remember last point
// faces
if (!e){ e=1; continue; } // ignore first slice of cone
i00=pnt.num- 3; i10=i00-N3;
i01=pnt.num-N3; i11=i01-N3;
for (j=0;j<N;j++)
{
fac.add(i00);
fac.add(i01);
fac.add(i11);
fac.add(i10);
i00=i01; i01+=3;
i10=i11; i11+=3;
}
}
}
}
//---------------------------------------------------------------------------
void spicule_draw() // render generated spicule
{
glEnable(GL_CULL_FACE);
glFrontFace(GL_CCW);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
int i,j;
glColor3f(1.0,1.0,1.0);
glBegin(GL_QUADS);
for (i=0;i<fac.num;i++)
{
j=fac.dat[i];
glNormal3dv(nor.dat+j);
glVertex3dv(pnt.dat+j);
}
glEnd();
}
//---------------------------------------------------------------------------
If you do not know how to compute vector operations like cross/dot products or absolute value see:
// cross product: W = U x V
W.x=(U.y*V.z)-(U.z*V.y)
W.y=(U.z*V.x)-(U.x*V.z)
W.z=(U.x*V.y)-(U.y*V.x)
// dot product: a = (U.V)
a=U.x*V.x+U.y*V.y+U.z*V.z
// abs of vector a = |U|
a=sqrt((U.x*U.x)+(U.y*U.y)+(U.z*U.z))
vector_mul(a[3],b[3],c[3]) is cross product a = b x c
a = vector_mul(b[3],c[3]) is dot product a = (b.c)
vector_one(a[3],b[3]) is unit vector a = b/|b|
vector_copy(a[3],b[3]) is just copy a = b
vector_add(a[3],b[3],c[3]) is adding a = b + c
vector_sub(a[3],b[3],c[3]) is substracting a = b - c
vector_neg(a[3],b[3]) is negation a = -b
vector_ld(a[3],x,y,z) is just loading a = (x,y,z)
Also some (if not all the) Vector math used can be found here:
Understanding 4x4 homogenous transform matrices
I also use mine dynamic list template so:
List<double> xxx; is the same as double xxx[];
xxx.add(5); adds 5 to end of the list
xxx[7] access array element (safe)
xxx.dat[7] access array element (unsafe but fast direct access)
xxx.num is the actual used size of the array
xxx.reset() clears the array and set xxx.num=0
xxx.allocate(100) preallocate space for 100 items

Ball to fixed ball collision [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I am trying to implement balls that change their direction when they hit an obstacle(in this case a fixed ball). I can detect when a collision occurs but I don't know how to modify the direction of a ball once it hits an obstacle. Here's some code:
struct Vec2
{
float x, y;
};
struct Ball
{
void onCollision(const Ball& fixedBall)
{
// This function will be called when a collision occurs
// Speed will be constant, only direction needs to change
}
void update()
{
position += direction * speed;
}
Vec2 position, direction; // direction is a normalized vector
float speed, radius;
};
You will need to invert the speed by negating it.
if (collision)
speed = speed * -1

Wormhole effect: warp space with opengl [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I am looking for a way to do a wormhole effect like this:
- https://www.youtube.com/watch?v=WeOBXmLeJWo&feature=youtu.be&t=43s
I have already found nice tunnels in the examples, but here it is a little bit more involved. Actually the space appears to be warped somehow and the movement is high velocity, so it is not just entering into a simple tunnel. Any idea how to do the space warping part of it?
I decided to add more info because this was too broad:
I have a galaxy and each star has a 3d coord, size, etc. in this galaxy. I can visit these stars with a space ship. There are very distant stars and it would take a lot of time to get to them, that's why I need warp (faster than light) speed. This does not necessarily requires a wormhole according to physics, but this app does not have to be overly realistic. I don't want to solve this with pure OpenGL so ofc. we can use shaders. I'd like to warp the space in the middle of the screen when accelerating to warp speeds. After that a tunnel effect can come, because I think it would consume a lot of resources to update every star by very high speeds, so I'd like to update only the close stars. This can't be a prerendered animation, because the destination is not always certain, so this has sometimes exploration purposes and sometimes traveling purposes. I don't think warping only the sky box is enough, but I am not sure about this.
There are 2 things going on there:
space curvature around the hole
You need to construct equation that describe the curvature of space around hole parametrized by hole parameters (mass,position,orientation) and time so you can animate it. Then from this curvature you can compute relative displacement of pixel/voxel around it. I would start with cylindrical cones with radius modulated by sin of the distance from hole +/- some animation parameters (need experimentation).
Something like this:
and for example start with (in wormhole local coordinates LCS):
r = R * sin(z*0.5*M_PI/wormhole_max_depth)
Then modulate it by additional therms. The wormhole_max_depth,R should be functions of time even linear or with some periodic therm so it is pulsating a bit.
The displacement can be done by simply computing distance of concerned point to cone surface and push it towards it the more the closer to the cone it is (inside cone voxels are considered below surface so apply max displacement strength)
particle/light/matter bursting out of the hole
I would go for this only when #1 is alredy done. It should be simple particle effect with some nice circular blended alpha texture animated on the surface of the cone from #1. I see it as few for loops with pseudo random displacement in position and speed ...
Techniques
This topic depends on how you want to do this. I see these possibilities:
Distort geometry during rendering (3D vector)
So you can apply the cone displacement directly on rendered stuff. This would be best applicable in GLSL but the geometry rendered must have small enough primitives to make this work on vertex level ...
Distort skybox/stars only (3D vector or 2D raster but objects stay unaffected)
So you apply the displacement on texture coordinates of skybox or directly on the star positions.
Distort whole rendered scene in second pass (2D raster)
This need to use 2 pass rendering and in the second pass just wrap the texture coordinates near hole.
As you got different local stars in each sector I would use star background generated from star catalogue (list of all your stars) And apply the distortion on them directly in 3D vector space (so no skybox.. option #2). And also because my engines already use such representation and rendering for the same reasons.
[Edit1] cone geometry
I haven't much time for this recently until today so I did not make much of a progress. I decided to start with cone geometry so here it is:
class wormhole
{
public:
reper rep; // coordinate system transform matrix
double R0,R1,H,t; // radiuses,depth
wormhole(){ R0=10.0; R1=100.0; H=50.0; t=0.0; };
wormhole(wormhole& a){ *this=a; };
~wormhole(){};
wormhole* operator = (const wormhole *a) { *this=*a; return this; };
/*wormhole* operator = (const wormhole &a) { ...copy... return this; };*/
void ah2xyz(double *xyz,double a,double h) // compute cone position from parameters a=<0,2pi>, h=<0,1>
{
double r,tt;
tt=t; if (t>0.5) tt=0.5; r=2.0*R0*tt; // inner radius R0
tt=t; if (t>1.0) tt=1.0; r+=(R1-r)*h*h*tt; // outer radius R1
xyz[0]=r*cos(a);
xyz[1]=r*sin(a);
xyz[2]=H*h*tt;
rep.l2g(xyz,xyz);
}
void draw_cone()
{
int e;
double a,h,da=pi2*0.04,p[3];
glColor3f(0.2,0.2,0.2);
for (h=0.0;h<=1.0;h+=0.1){ glBegin(GL_LINE_STRIP); for (e=1,a=0.0;e;a+=da) { if (a>=pi2) { e=0; a=0.0; } ah2xyz(p,a,h); glVertex3dv(p); } glEnd(); }
for (e=1,a=0.0;e;a+=da){ glBegin(GL_LINE_STRIP); for (h=0.0;h<=1.0;h+=0.1) { if (a>=pi2) { e=0; a=0.0; } ah2xyz(p,a,h); glVertex3dv(p); } glEnd(); }
}
} hole;
Where rep is my class for homogenous 4x4 transform matrix (remembering both direct and inverse matrices at the same time) function l2g just transforms from local coordinates to global. The cone parameters are:
R0 - inner cone radius when fully grown
R1 - outer cone radius when fully grown
H - the height/depth of the cone when fully grown
t - is animation parameter values <0.0,1.0> are the growth and values above 1.0 are reserved for wormhole fully grown animation
Here how it looks like:
What I would do is simply calculate a vector from the texture coordinate of the screen center to the texture coordinate of the pixel you're shading.
Then modify that vector in any way you want (time based for example) and apply it to the texture coordinate of the pixel you're shading and then use the resulting coordinate to sample your texture.
In pseudocode this would be something like this:
vec2 vector_to_screen_center = vec2(0.5) - texture_coordinate;
texture_coordinate += vector_to_screen_center * sin(time) * 0.1; // Time based modulation of the vector.
gl_FragColor = texture2D(screen_texture, texture_coordinate);
Your question does not have a GLSL tag. If you plan to do this without shaders, this is going to be hard and/or inefficient.

OPENGL Terrain from text file [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I am trying to create terrain which takes height values from txt file .
During my search I realized that generally the terrains are created from bmp files or another kind of picture taking values from pixels. I read height values from file into a 2d array.
void File(){
FILE* file = fopen("data.txt", "r"); // data.txt opened with read only mode to get heights
int i,j;
for (i = 0; i < 17; i++){
for (j = 0; j < 21; j++){
fscanf(file, "%d", &data[i][j]);
}
}
fclose(file);
}
and then load these values to vertex to create triangle.
But there are triangles everywhere when I change the x y z values .
The intended project is to create a terrain.
Is there a special way or code to create terrain by using just height values from a txt file?
OpenGL renders primitives like triangles and triangle strips. You'll need to convert your terrain heightmap into primitives that OpenGL understands.
Perhaps this tutorial found by a quick google search can help you.
http://www.codeproject.com/Articles/14154/OpenGL-Terrain-Generation-An-Introduction
Depending on how the data looks in the heightmap, say its in the format of vertex/height.
You could read in a line, say its
v 1.7/2.1/3.7 h 10
store off the vertex and translate that vertex up 10 (height).
Repeat for each vertex and connect them with faces.
If it's just height values then you could substitue in arbitrary verticies for each height value.
I.E.
heightmap:
h 10
h 20
h 30
Then as a function:
void generateTerrain(int length, int width)
{
for(;length>= 0; --length)
{
for(; width >= 0; --width)
{
//read line from file
//store the height in a temp hieght variable
//createVertex(length, width, height);
//store this vertex somewhere for later
}
}
}
There are probably way more efficient ways of doing that, but for simple terrain generation that just popped in my head :)