How to make the ends of Cylinder transparent in JavaFX - java

I'm currently trying to make the ends of a Cylinder completely transparent whilst keeping the sides a Material.
I'm unsure how to achieve this. This thread mentions it but all the links are broken
I think I need to use a clipping plane? Although I don't know where to start with that.
Here's what I'm currently using to just simply set a translucent material!
Cylinder line = new Cylinder(getRadius()/4, height);
lineMaterial = new PhongMaterial();
lineMaterial.setDiffuseColor(new Color(1,1,1,0.5));
lineMaterial.diffuseMapProperty();
line.setMaterial(lineMaterial);

One possible way to get transparency is by using a png as the diffuse image, with some transparent pixels.
While this works, if you apply over a built-in JavaFX Cylinder, you won't get the expected result, because the Cylinder applies the same image to both the vertical tube and the two cap faces. So this won't work for your case.
There could be an option to remove the caps from the cylinder mesh and get just a tube, but unfortunately it doesn't export its triangle mesh.
So far, the best option is to create directly the mesh of a tube, and for that we can reuse the mesh of the Cylinder by checking the open source code at the (new) OpenJDK/JFX GitHub repository.
The following method creates a TriangleMesh of a Tube of height h, radius r, with div divisions (producing 2 * div triangles). It is the exact same code as the one in Cylinder, but without the caps points, texture coordinate and faces arrays.
private static TriangleMesh createMesh(int div, float h, float r) {
final int nPoints = div * 2;
final int tcCount = (div + 1) * 2;
final int faceCount = div * 2;
float textureDelta = 1.f / 256;
float dA = 1.f / div;
h *= .5f;
float points[] = new float[nPoints * 3];
float tPoints[] = new float[tcCount * 2];
int faces[] = new int[faceCount * 6];
int smoothing[] = new int[faceCount];
int pPos = 0, tPos = 0;
for (int i = 0; i < div; ++i) {
double a = dA * i * 2 * Math.PI;
points[pPos + 0] = (float) (Math.sin(a) * r);
points[pPos + 1] = h;
points[pPos + 2] = (float) (Math.cos(a) * r);
tPoints[tPos + 0] = 1 - dA * i;
tPoints[tPos + 1] = 1 - textureDelta;
pPos += 3; tPos += 2;
}
// top edge
tPoints[tPos + 0] = 0;
tPoints[tPos + 1] = 1 - textureDelta;
tPos += 2;
for (int i = 0; i < div; ++i) {
double a = dA * i * 2 * Math.PI;
points[pPos + 0] = (float) (Math.sin(a) * r);
points[pPos + 1] = -h;
points[pPos + 2] = (float) (Math.cos(a) * r);
tPoints[tPos + 0] = 1 - dA * i;
tPoints[tPos + 1] = textureDelta;
pPos += 3; tPos += 2;
}
// bottom edge
tPoints[tPos + 0] = 0;
tPoints[tPos + 1] = textureDelta;
tPos += 2;
int fIndex = 0;
// build body faces
for (int p0 = 0; p0 < div; ++p0) {
int p1 = p0 + 1;
int p2 = p0 + div;
int p3 = p1 + div;
// add p0, p1, p2
faces[fIndex+0] = p0;
faces[fIndex+1] = p0;
faces[fIndex+2] = p2;
faces[fIndex+3] = p2 + 1;
faces[fIndex+4] = p1 == div ? 0 : p1;
faces[fIndex+5] = p1;
fIndex += 6;
// add p3, p2, p1
faces[fIndex+0] = p3 % div == 0 ? p3 - div : p3;
faces[fIndex+1] = p3 + 1;
faces[fIndex+2] = p1 == div ? 0 : p1;
faces[fIndex+3] = p1;
faces[fIndex+4] = p2;
faces[fIndex+5] = p2 + 1;
fIndex += 6;
}
for (int i = 0; i < div * 2; ++i) {
smoothing[i] = 1;
}
TriangleMesh m = new TriangleMesh();
m.getPoints().setAll(points);
m.getTexCoords().setAll(tPoints);
m.getFaces().setAll(faces);
m.getFaceSmoothingGroups().setAll(smoothing);
return m;
}
Now you will need to create a MeshView so you can add it to your scene:
private static MeshView createTube(int div, float h, float r) {
MeshView meshView = new MeshView(createMesh(div, h, r));
// meshView.setDrawMode(DrawMode.LINE);
meshView.setCullFace(CullFace.NONE);
PhongMaterial material = new PhongMaterial(Color.RED);
meshView.setMaterial(material);
return meshView;
}
Create and add one to your scene:
MeshView tube = createTube(64, 5f, 1.6f);
Scene scene = new Scene(new Group(tube), 600, 600, true, SceneAntialiasing.BALANCED);
And you will get your tube:
You can also apply a diffuse image as texture:
material.setDiffuseMap(new Image(getClass.getResourceAsStream("440px-JavaFX_Logo.png")));

Related

OpenGL ES2.0 Unable to generate proper sphere vertices with texture coordinates in a function in Android java

I am trying to run video on 3d surfaces in android.
I am able to run it properly on a squareso I proceeded for a sphere.
I found multiple algorithms and functions to generate sphere vertices and tex coords with or without indexes and tried them.
Below are the two functions that are partially working
1st gives improperly mapped textures
public void sphere(final int depth, final float radius) {
// Clamp depth to the range 1 to MAXIMUM_ALLOWED_DEPTH;
final int d = Math.max(1, Math.min(MAXIMUM_ALLOWED_DEPTH, depth));
// Calculate basic values for the sphere.
this.mTotalNumStrips = power(2, d - 1) * VERTEX_MAGIC_NUMBER;
numVerticesPerStrip = power(2, d) * 3;
final double altitudeStepAngle = ONE_TWENTY_DEGREES / power(2, d);
final double azimuthStepAngle = THREE_SIXTY_DEGREES / mTotalNumStrips;
double x, y, z, h, altitude, azimuth; int vertexPos = 0;
int texturePos = 0;
//textureBuffer= new ArrayList<FloatBuffer>();
/** Mapping texture coordinates for the vertices. */
//mTexture = new ArrayList<float[]>();
//mVertices= new ArrayList<float[]>();
//mVertices = new float[numVerticesPerStrip * NUM_FLOATS_PER_VERTEX *mTotalNumStrips]; // NOPMD
// mTexture = new float[numVerticesPerStrip * NUM_FLOATS_PER_TEXTURE * mTotalNumStrips]; // NOPMD
/*for (int stripNum = 0; stripNum < this.mTotalNumStrips; stripNum++) {
// Setup arrays to hold the points for this strip.
// Calculate position of the first vertex in this strip.
altitude = NINETY_DEGREES;
azimuth = stripNum * azimuthStepAngle;
// Draw the rest of this strip.
for (int vertexNum = 0; vertexNum < numVerticesPerStrip; vertexNum += 2) {
// First point - Vertex.
y = radius * Math.sin(altitude);
h = radius * Math.cos(altitude);
z = h * Math.sin(azimuth);
x = h * Math.cos(azimuth);
mVertices[vertexPos++] = (float) x;
mVertices[vertexPos++] = (float) y;
mVertices[vertexPos++] = (float) z;
// First point - Texture.
mTexture[texturePos++] = (float) (1 - azimuth / THREE_SIXTY_DEGREES);
mTexture[texturePos++] = (float) (1 - (altitude + NINETY_DEGREES) / ONE_EIGHTY_DEGREES);
// Second point - Vertex.
altitude -= altitudeStepAngle;
azimuth -= azimuthStepAngle / 2.0;
y = radius * Math.sin(altitude);
h = radius * Math.cos(altitude);
z = h * Math.sin(azimuth);
x = h * Math.cos(azimuth);
mVertices[vertexPos++] = (float) x;
mVertices[vertexPos++] = (float) y;
mVertices[vertexPos++] = (float) z;
// Second point - Texture.
mTexture[texturePos++] = (float) (1 - azimuth / THREE_SIXTY_DEGREES);
mTexture[texturePos++] = (float) (1 - (altitude + NINETY_DEGREES) / ONE_EIGHTY_DEGREES);
azimuth += azimuthStepAngle;
}
*/
mVertices = new float[numVerticesPerStrip * NUM_FLOATS_PER_VERTEX *mTotalNumStrips]; // NOPMD
mTexture = new float[numVerticesPerStrip * NUM_FLOATS_PER_TEXTURE*mTotalNumStrips]; // NOPMD
for (int stripNum = 0; stripNum < this.mTotalNumStrips; stripNum++) {
// Setup arrays to hold the points for this strip.
// int vertexPos = 0;
// int texturePos = 0;
// Calculate position of the first vertex in this strip.
altitude = NINETY_DEGREES;
azimuth = stripNum * azimuthStepAngle;
// Draw the rest of this strip.
for (int vertexNum = 0; vertexNum < numVerticesPerStrip; vertexNum += 2) {
// First point - Vertex.
y = radius * Math.sin(altitude);
h = radius * Math.cos(altitude);
z = h * Math.sin(azimuth);
x = h * Math.cos(azimuth);
mVertices[vertexPos++] = (float) x;
mVertices[vertexPos++] = (float) y;
mVertices[vertexPos++] = (float) z;
// First point - Texture.
mTexture[texturePos++] = (float) (1.0 - azimuth / THREE_SIXTY_DEGREES);
mTexture[texturePos++] = (float) (1.0 - (altitude + NINETY_DEGREES) / ONE_EIGHTY_DEGREES);
// Second point - Vertex.
altitude -= altitudeStepAngle;
azimuth -= azimuthStepAngle / 2.0;
y = radius * Math.sin(altitude);
h = radius * Math.cos(altitude);
z = h * Math.sin(azimuth);
x = h * Math.cos(azimuth);
mVertices[vertexPos++] = (float) x;
mVertices[vertexPos++] = (float) y;
mVertices[vertexPos++] = (float) z;
// Second point - Texture.
mTexture[texturePos++] = (float) (1.0 - azimuth / THREE_SIXTY_DEGREES);
mTexture[texturePos++] = (float) (1.0 - (altitude + NINETY_DEGREES) / ONE_EIGHTY_DEGREES);
azimuth += azimuthStepAngle;
}
// this.mVertices.add(mVertices);
// this.mTexture.add(textureBuffer);
}
}
The 2nd working function gives me only half sphere on right side
The function is as below
public void Sphere3D(//context:Context3D,
int slices,
int stacks)
// double posX, double posY,double posZ,
// double scaleX, double scaleY,double scaleZ)
{
// Make the model->world transformation matrix to position and scale the sphere
// Cap parameters
if (slices < MIN_SLICES)
{
slices = MIN_SLICES;
}
if (stacks < MIN_STACKS)
{
stacks = MIN_STACKS;
}
// Data we will later upload to the GPU
//var positions:Vector.<Number>;
//var texCoords:Vector.<Number>;
//var tris:Vector.<uint>;
// Pre-compute many constants used in tesselation
final double stepTheta = (2.0*Math.PI) / slices;
final double stepPhi = Math.PI / stacks;
final double stepU = 1.0 / slices;
final double stepV = 1.0 / stacks;
final int verticesPerStack = slices + 1;
final int numVertices = verticesPerStack * (stacks+1);
// Allocate the vectors of data to tesselate into
//positions = new Vector.<Number>(numVertices*3);
mVertices=new float[numVertices*3];
//texCoords = new Vector.<Number>(numVertices*2);
mTexture=new float[numVertices*2];
//tris = new Vector.<uint>(slices*stacks*6);
mIndexes= new short[slices*stacks*6];
// Pre-compute half the sin/cos of thetas
double halfCosThetas[] = new double[verticesPerStack];
double halfSinThetas[] = new double[verticesPerStack];
int curTheta= 0;
for (int slice=0; slice < verticesPerStack; ++slice)
{
halfCosThetas[slice] = Math.cos(curTheta) * 0.5;
halfSinThetas[slice] = Math.sin(curTheta) * 0.5;
curTheta += stepTheta;
}
// Generate positions and texture coordinates
double curV = 1.0;
double curPhi = Math.PI;
int posIndex=0;
int texCoordIndex=0;
for (int stack = 0; stack < stacks+1; ++stack)
{
double curU = 1.0;
double curY = Math.cos(curPhi) * 0.5;
double sinCurPhi = Math.sin(curPhi);
for (int slice = 0; slice < verticesPerStack; ++slice)
{
mVertices[posIndex++] = (float)(halfCosThetas[slice]*sinCurPhi);
mVertices[posIndex++] =(float) curY;
mVertices[posIndex++] = (float)(halfSinThetas[slice] * sinCurPhi);
mTexture[texCoordIndex++] = (float)curU;
mTexture[texCoordIndex++] = (float)curV;
curU -= stepU;
}
curV -= stepV;
curPhi -= stepPhi;
}
// Generate tris
int lastStackFirstVertexIndex= 0;
int curStackFirstVertexIndex = verticesPerStack;
int triIndex=0;
for (int stack = 0; stack < stacks; ++stack)
{
for (int slice = 0; slice < slices; ++slice)
{
// Bottom tri of the quad
mIndexes[triIndex++] = (short)(lastStackFirstVertexIndex + slice + 1);
mIndexes[triIndex++] = (short)(curStackFirstVertexIndex + slice);
mIndexes[triIndex++] = (short)(lastStackFirstVertexIndex + slice);
// Top tri of the quad
mIndexes[triIndex++] =(short)( lastStackFirstVertexIndex + slice + 1);
mIndexes[triIndex++] =(short)( curStackFirstVertexIndex + slice + 1);
mIndexes[triIndex++] =(short)( curStackFirstVertexIndex + slice);
}
lastStackFirstVertexIndex += verticesPerStack;
curStackFirstVertexIndex += verticesPerStack;
}
// Create vertex and index buffers
/*this.positions = context.createVertexBuffer(positions.length/3, 3);
this.positions.uploadFromVector(positions, 0, positions.length/3);
this.texCoords = context.createVertexBuffer(texCoords.length/2, 2);
this.texCoords.uploadFromVector(texCoords, 0, texCoords.length/2);
this.tris = context.createIndexBuffer(tris.length);
this.tris.uploadFromVector(tris, 0, tris.length);*/
}
what I need is mVertices , mIndees and mTexture to be filled with vertices , indices and texture respectively and if the function does not create indexed coordinates I am drawing normally.
I have been trying to understand the algorithm and detect the issue in both of them but unable to get any leads.
Please let me know if further information is required

Image over another already drawn image in CAPTCHA

I want to generate a captcha by myself without using any other API, but here are some issues. In my code I have treated each character as an image and then form some operation on them but now I want to rotate whole image with respect to its midpoint.
Here is my sample code:
for (int i = 0; i < charsToPrint; i++)
{
double randomValue =Math.random();
int randomIndex = (int) Math.round(randomValue * (chars.length - 1));
char characterToShow = chars[randomIndex];
finalString.append(characterToShow);
int charWidth = fontMetrics.charWidth(characterToShow);
int charDim = Math.max(maxAdvance, fontHeight);
//int halfCharDim = (int) (charDim / 2);
charImage = new BufferedImage(charDim, charDim,BufferedImage.TYPE_INT_ARGB);
charGraphics = charImage.createGraphics();
charGraphics.setColor(textColor);
charGraphics.setFont(textFont);
int rn = ran.nextInt((20 - 10) + 1) + 10;
x1=charDim/rn;
int rn1 = ran.nextInt((20 - 10) + 1) + 10;
y1=charDim/rn1;
int charX = (int) ((0.5 * charDim - 0.5 * charWidth)+x1);
int charY=(int) ((charDim - fontMetrics.getAscent()) / 2 + fontMetrics.getAscent()+y1);
charGraphics.drawString("" + characterToShow, charX, charY);
float x = horizMargin + spacePerChar * (i) - charDim / 2.0f;
int y = (int) ((height - charDim) / 2);
g.setColor(Color.GREEN);
g.drawImage(charImage, (int) (x+x1), (int)(y+y1), charDim,charDim, null,null);
charGraphics.dispose();
}

Convert Vec4i to Java openCV

I'm new to OpenCV in Android. I'm trying to covert a C++ code into Java. I am stuck in some point that I cannot continue.
std::vector<cv::Vec4i> lines;
cv::HoughLinesP(bw, lines, 1, CV_PI/180, 70, 30, 10);
// Expand the lines
for (int i = 0; i < lines.size(); i++)
{
cv::Vec4i v = lines[i];
lines[i][0] = 0;
lines[i][1] = ((float)v[1] - v[3]) / (v[0] - v[2]) * -v[0] + v[1];
lines[i][2] = src.cols;
lines[i][3] = ((float)v[1] - v[3]) / (v[0] - v[2]) * (src.cols - v[2]) + v[3];
}
half way I converted.. upto the TODO
MatOfInt4 lines= new MatOfInt4();
Imgproc.HoughLinesP(bw, lines, 1, Math.PI/180, 70, 30, 10);
int[] lineArray = lines.toArray();
// Expand the lines
//TODO
for (int i = 0; i < lineArray.length; i++)
{
int v = lineArray[i];
lines.[i][0] = 0;
lines[i][1] = ((float)v[1] - v[3]) / (v[0] - v[2]) * -v[0] + v[1];
lines[i][2] = src.cols();
lines[i][3] = ((float)v[1] - v[3]) / (v[0] - v[2]) * (src.cols() - v[2]) + v[3];
}
which I'm confused is inside the for loop. when converted lines in to a Array it gives a int array. But inside the for loop again v is defined which should be a array. I didn't get this point. Can anybody please help me to get through this. Thank you in advance.
Finally I managed to write the working code. with help of this link
Mat lines = new Mat();
int threshold = 70;
int minLineSize = 30;
int lineGap = 10;
Imgproc.HoughLinesP(thresholdImage, lines, 1, Math.PI / 180, threshold,
minLineSize, lineGap);
for (int x = 0; x < lines.cols(); x++) {
double[] vec = lines.get(0, x);
double[] val = new double[4];
val[0] = 0;
val[1] = ((float) vec[1] - vec[3]) / (vec[0] - vec[2]) * -vec[0] + vec[1];
val[2] = src.cols();
val[3] = ((float) vec[1] - vec[3]) / (vec[0] - vec[2]) * (src.cols() - vec[2]) + vec[3];
lines.put(0, x, val);
}

Texture Mapping is reversed! Java3D

I could use some extra eyes to help me see why my texture map is reversed on my object. It prints backwards -- as if seeing it in a mirror. I had suspected that maybe reversing the indices would help, but that just changed where it was mapped without reversing the reversal.
public class MobiusBanner extends Applet {
public static void main(String[] args) {
new MainFrame(new MobiusBanner(), 800, 600);
}
#Override
public void init() {
GraphicsConfiguration gc = SimpleUniverse.getPreferredConfiguration();
Canvas3D canvas = new Canvas3D(gc);
this.setLayout(new BorderLayout());
this.add(canvas, BorderLayout.CENTER);
SimpleUniverse su = new SimpleUniverse(canvas);
su.getViewingPlatform().setNominalViewingTransform();
BranchGroup bg = createSceneGraph();
bg.compile();
su.addBranchGraph(bg);
}
private BranchGroup createSceneGraph() {
BranchGroup root = new BranchGroup();
Shape3D shape = new Shape3D();
shape.setGeometry(mobius().getIndexedGeometryArray());
//Scaling transform
Transform3D tr = new Transform3D();
tr.setScale(0.5);
//Spin transform group
TransformGroup spin = new TransformGroup();
spin.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
spin.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
root.addChild(spin);
//Set appearance
Appearance ap = createTextureAppearance();
ap.setPolygonAttributes(new PolygonAttributes(PolygonAttributes.POLYGON_FILL,
PolygonAttributes.CULL_BACK, 0));
//Set materials
Material mat = new Material();
mat.setLightingEnable(true);
mat.setShininess(30);
ap.setMaterial(mat);
//Overarching Transform group
TransformGroup tg = new TransformGroup(tr);
tg.addChild(shape);
spin.addChild(tg);
shape.setAppearance(ap);
//Set rotation
MouseRotate rotator = new MouseRotate(spin);
BoundingSphere bounds = new BoundingSphere();
rotator.setSchedulingBounds(bounds);
spin.addChild(rotator);
//Set translation
MouseTranslate translator = new MouseTranslate(spin);
translator.setSchedulingBounds(bounds);
spin.addChild(translator);
//Set zoom
MouseZoom zoom = new MouseZoom(spin);
zoom.setSchedulingBounds(bounds);
spin.addChild(zoom);
//Set background
Background background = new Background(1.0f, 1.0f, 1.0f);
background.setApplicationBounds(bounds);
root.addChild(background);
f//Set lighting
AmbientLight light = new AmbientLight(true, new Color3f(Color.BLACK));
light.setInfluencingBounds(bounds);
root.addChild(light);
PointLight ptlight = new PointLight(new Color3f(Color.white),
new Point3f(0.5f, 0.5f, 1f),
new Point3f(1f, 0.2f, 0f));
ptlight.setInfluencingBounds(bounds);
root.addChild(ptlight);
return root;
}//Close branchgroup method
//Create the Mobius shape
private GeometryInfo mobius() {
int m = 100; //number of row points
int n = 100; //number of col points
int p = 4 * ((m - 1) * (n - 1)); //faces * points per face
IndexedQuadArray iqa = new IndexedQuadArray(m * n,
GeometryArray.COORDINATES | GeometryArray.TEXTURE_COORDINATE_2, p);
Point3d[] vertices = new Point3d[m * n];
int index = 0;
//Create vertices
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
double u = i * (4 * (Math.PI)) / (m - 1);
double v = -0.3 + (j * (0.6 / (n - 1)));
double x = (1 + v * Math.cos(u / 2)) * Math.cos(u);
double y = (1 + v * Math.cos(u / 2)) * Math.sin(u);
double z = v * Math.sin(u / 2);
vertices[index] = new Point3d(x, y, z);
index++;
}//close nested for loop
}//close for loop
index = 0;
//set texture coordinates
TexCoord2f[] tex = new TexCoord2f[m * n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
tex[index] = new TexCoord2f();
tex[index] = new TexCoord2f(i * 1f / m, j * 1f / n);
index++;
}
}
iqa.setCoordinates(0, vertices);
iqa.setTextureCoordinates(0, 0, tex);
index = 0;
//set index for coordinates
int[] texIndices = new int[p];
for (int i = 0; i < m - 1; i++) {
for (int j = 0; j < n - 1; j++) {
iqa.setCoordinateIndex(index, i * m + j);
texIndices[index] = i * m + j;
index++;
iqa.setCoordinateIndex(index, i * m + j + 1);
texIndices[index] = i * m + j + 1;
index++;
iqa.setCoordinateIndex(index, (i + 1) * m + j + 1);
texIndices[index] = (i + 1) * m + j + 1;
index++;
iqa.setCoordinateIndex(index, (i + 1) * m + j);
texIndices[index] = (i + 1) * m + j;
index++;
}//close nested for loop
}//close for loop
iqa.setTextureCoordinateIndices(0, 0, texIndices);
//create geometry info and generate normals for shape
GeometryInfo gi = new GeometryInfo(iqa);
NormalGenerator ng = new NormalGenerator();
ng.generateNormals(gi);
return gi;
}
Appearance createTextureAppearance() {
Appearance ap = new Appearance();
BufferedImage bi = new BufferedImage(1024, 128,
BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = (Graphics2D) bi.getGraphics();
g2.setColor(Color.white);
g2.fillRect(0, 0, 1024, 128);
g2.setFont(new Font("Serif", Font.BOLD, 36));
g2.setColor(new Color(200, 0, 0));
g2.drawString("Mobius Strip", 0, 100);
ImageComponent2D image = new ImageComponent2D(ImageComponent2D.FORMAT_RGBA, bi);
Texture2D texture = new Texture2D(Texture.BASE_LEVEL, Texture.RGBA,
image.getWidth(), image.getHeight());
texture.setImage(0, image);
texture.setMagFilter(Texture.BASE_LEVEL_LINEAR);
ap.setTexture(texture);
//Combine Texture and Lighting
TextureAttributes textatt = new TextureAttributes();
textatt.setTextureMode(TextureAttributes.COMBINE);
ap.setTextureAttributes(textatt);
ap.setMaterial(new Material());
return ap;
}
}
You want to reverse only one of the texture coordinates, not both. Try changing
tex[index] = new TexCoord2f(i * 1f / m, j * 1f / n);
to
tex[index] = new TexCoord2f((m-1-i) * 1f / m, j * 1f / n);
or
tex[index] = new TexCoord2f(i * 1f / m, (n-1-j) * 1f / n);

Problems with making 2D terrain in OpenGL

Some time ago I asked this question about how to make a 2D terrain with opengl vertices. I got a good answer, but when trying it out it didn't draw anything, and I can't figure out what's wrong, or how to fix it.
I have this now :
public class Terrain extends Actor {
Mesh mesh;
private final int LENGTH = 1500; //length of the whole terrain
public Terrain(int res) {
Random r = new Random();
//res (resolution) is the number of height-points
//minimum is 2, which will result in a box (under each height-point there is another vertex)
if (res < 2)
res = 2;
mesh = new Mesh(VertexDataType.VertexArray, true, 2 * res, 50, new VertexAttribute(Usage.Position, 2, "a_position"));
float x = 0f; //current position to put vertices
float med = 100f; //starting y
float y = med;
float slopeWidth = (float) (LENGTH / ((float) (res - 1))); //horizontal distance between 2 heightpoints
// VERTICES
float[] tempVer = new float[2*2*res]; //hold vertices before setting them to the mesh
int offset = 0; //offset to put it in tempVer
for (int i = 0; i<res; i++) {
tempVer[offset+0] = x; tempVer[offset+1] = 0f; // below height
tempVer[offset+2] = x; tempVer[offset+3] = y; // height
//next position:
x += slopeWidth;
y += (r.nextFloat() - 0.5f) * 50;
offset +=4;
}
mesh.setVertices(tempVer);
// INDICES
short[] tempIn = new short[(res-1)*6];
offset = 0;
for (int i = 0; i<res; i+=2) {
tempIn[offset + 0] = (short) (i); // below height
tempIn[offset + 1] = (short) (i + 2); // below next height
tempIn[offset + 2] = (short) (i + 1); // height
tempIn[offset + 3] = (short) (i + 1); // height
tempIn[offset + 4] = (short) (i + 2); // below next height
tempIn[offset + 5] = (short) (i + 3); // next height
offset+=6;
}
}
#Override
public void draw(SpriteBatch batch, float delta) {
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
mesh.render(GL10.GL_TRIANGLES);
}
This is being rendered by Libgdx, which also provides the class Mesh, but this is not really relevant since I believe that works fine. My problems lay by the vertex and indices generation. I don't really know how to debug it either, so could anyone please look at it, and help me to find why nothing is being rendered?
After a full day has passed, and I have tried everything to solve it, it seemed I forgot to actually set the indices to the mesh.
mesh.setIndices(tempIn);
One missing line, hours of pain... i'm an idiot :)

Categories