I'm a new to LibGDX 3D facilities and I'm wondering how I can merge two cylinders created using the ModelBuilder#createCylinder class.I have two ModelInstances :
The first one is a white cylinder,
The second a red cylinder with the same properties
How can get only one cylinder to render (instance / model / object / whatever can be rendered) composed of the red above the white one (or vice versa).
Pixmap pixmap1 = new Pixmap(1, 1, Format.RGBA8888);
pixmap1.setColor(Color.WHITE);
pixmap1.fill();
Texture white = new Texture(pixmap1);
//...
Texture red = new Texture(pixmap2);
model1 = modelBuilder.createCylinder(4f, 6f, 4f, 16,
new Material(
TextureAttribute.createDiffuse(white),
ColorAttribute.createSpecular(1,1,1,1),
FloatAttribute.createShininess(8f))
, Usage.Position | Usage.Normal | Usage.TextureCoordinates);
model1I_white = new ModelInstance(model1, 0, 0, 0);
//...
model2I_red = new ModelInstance(model2, 0, 0, -2f);
Then I render ModelInstance with ModelBatch#render.
Instead of using createCylinder(), you can create 2 cylinders with the MeshBuilder class, and compose your final cylinder with part().
meshBuilder.begin();
meshBuilder.cylinder(4f, 6f, 4f, 16);
Mesh cylinder1 = meshBuilder.end();
meshBuilder.begin();
meshBuilder.cylinder(4f, 6f, 4f, 16);
Mesh cylinder2 = meshBuilder.end();
modelBuilder.begin();
modelBuilder.part("cylinder1",
cylinder1,
Usage.Position | Usage.Normal | Usage.TextureCoordinates,
new Material(
TextureAttribute.createDiffuse(white),
ColorAttribute.createSpecular(1,1,1,1),
FloatAttribute.createShininess(8f)));
modelBuilder.part("cylinder2",
cylinder2,
Usage.Position | Usage.Normal | Usage.TextureCoordinates,
new Material(
TextureAttribute.createDiffuse(red),
ColorAttribute.createSpecular(1,1,1,1),
FloatAttribute.createShininess(8f)))
.mesh.transform(new Matrix4().translate(0, 0, -2f));
Model finalCylinder = modelBuilder.end();
Thanks a lot to Aurel for sharing the code.
Probably libGdx's Api changed slightly so I'll post the complete code wich worked for me
MeshBuilder meshBuilder = new MeshBuilder();
meshBuilder.begin(VertexAttributes.Usage.Position | VertexAttributes.Usage.Normal);
meshBuilder.part("id1", GL20.GL_TRIANGLES);
meshBuilder.box(1f, 1f, 1f);
Mesh mesh1 = meshBuilder.end();
meshBuilder.begin(VertexAttributes.Usage.Position | VertexAttributes.Usage.Normal);
meshBuilder.part("id2", GL20.GL_TRIANGLES);
meshBuilder.cylinder(1f, 1f, 1f, 16);
Mesh mesh2 = meshBuilder.end();
ModelBuilder modelBuilder = new ModelBuilder();
modelBuilder.begin();
modelBuilder.part("part1",
mesh1,
GL20.GL_TRIANGLES,
new Material(ColorAttribute.createDiffuse(Color.RED)));
modelBuilder.part("part2",
mesh2,
GL20.GL_TRIANGLES,
new Material(ColorAttribute.createDiffuse(Color.RED)))
.mesh.transform(new Matrix4().translate(1, 0, 0f));
To preserve a color for every mesh add VertxtAttributes.Usage.ColorPacked as meshBuilder.begin()
meshBuilder.begin(VertexAttributes.Usage.Position | VertexAttributes.Usage.Normal | VertexAttributes.Usage.ColorPacked);
Related
I'm writing a 3D game in Java using libGDX. In my game there's a model instance of a room which his walls are just rectangles. I'm tryimg to add an effect of "bullet holes" which are just a texture that appear on the wall when the player shoots at it. I'm trying to figure what the optimal way to implement it? The obvious way is just creating a model instance that built from a single rect with the hole texture for each bullet hole - but this way there will be a draw call for each one of these holes, which is not performance-wise AFAIK.
A piece of code which I create the walls:
Texture wallTexture = new Texture(Gdx.files.internal("wall.png"));
wallTexture.setWrap(Texture.TextureWrap.Repeat, Texture.TextureWrap.Repeat);
Material wallMaterial = new Material(TextureAttribute.createDiffuse(wallTexture));
MeshPartBuilder meshBuilder = modelBuilder.part("walls", GL20.GL_TRIANGLES,
VertexAttributes.Usage.Position | VertexAttributes.Usage.Normal |
VertexAttributes.Usage.TextureCoordinates, wallMaterial);
meshBuilder.setUVRange(0, 0, C.ROOM_SIZE, 3);
corner00.set(C.ROOM_SIZE, 0, 0);
corner10.set(0, 0, 0);
corner11.set(0, 0, 6);
corner01.set(C.ROOM_SIZE, 0, 6);
normal.set(0, 1, 0);
line1000.setNormalDirection(auxVector2.set(0, 1).angle());
meshBuilder.rect(corner00, corner10, corner11, corner01, normal);
corner00.set(C.ROOM_SIZE, C.ROOM_SIZE, 0);
corner10.set(C.ROOM_SIZE, 0, 0);
corner11.set(C.ROOM_SIZE, 0, 6);
corner01.set(C.ROOM_SIZE, C.ROOM_SIZE, 6);
normal.set(-1, 0, 0);
line1110.setNormalDirection(auxVector2.set(-1, 0).angle());
meshBuilder.rect(corner00, corner10, corner11, corner01, normal);
corner00.set(0, C.ROOM_SIZE, 0);
corner10.set(C.ROOM_SIZE, C.ROOM_SIZE, 0);
corner11.set(C.ROOM_SIZE, C.ROOM_SIZE, 6);
corner01.set(0, C.ROOM_SIZE, 6);
normal.set(0, -1, 0);
line0111.setNormalDirection(auxVector2.set(0, -1).angle());
meshBuilder.rect(corner00, corner10, corner11, corner01, normal);
corner00.set(0, 0, 0);
corner10.set(0, C.ROOM_SIZE, 0);
corner11.set(0, C.ROOM_SIZE, 6);
corner01.set(0, 0, 6);
normal.set(1, 0, 0);
line0001.setNormalDirection(auxVector2.set(1, 0).angle());
meshBuilder.rect(corner00, corner10, corner11, corner01, normal);
Model levelModel = modelBuilder.end();
levelModelInstance = new ModelInstance(levelModel);
This part occurs only once upon loading the level. The bullet holes are supposed to appear in-game.
I am trying to implement shadow-mapping in my scene, but all I get is zeros in my fragment shader when I call texture() (I've tested it with == 0.0). My question: Am I sending the depth texture to the shader correctly?
Here is my fragment shader code:
bool getShadow() {
vec4 lightProjPositionScaled = lightProjPosition/lightProjPosition.w;
vec2 texCoords = lightProjPositionScaled.xy*0.5 + 0.5; // bias
return lightProjPositionScaled.z + 0.0005 > texture(shadowMap, texCoords).x;
}
Here is my relevant java codeInit (edited due to BDL's comment)
gl.glEnable(GL2.GL_TEXTURE_2D);
// generate stuff
IntBuffer ib = IntBuffer.allocate(1);
gl.glGenFramebuffers(1, ib);
frameBuffer = ib.get(0);
ib = IntBuffer.allocate(1);
gl.glGenTextures(1, ib);
shadowMap = ib.get(0);
gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, frameBuffer);
gl.glBindTexture(GL2.GL_TEXTURE, shadowMap);
gl.glTexImage2D(GL2.GL_TEXTURE_2D, 0, GL2.GL_DEPTH_COMPONENT, 1024, 1024, 0, GL2.GL_DEPTH_COMPONENT, GL2.GL_FLOAT, null);
gl.glDrawBuffer(GL2.GL_NONE);
gl.glReadBuffer(GL2.GL_NONE);
gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, 0);
// prevents 'shadow acne'
gl.glPolygonOffset(2.5f, 0);
// prevents multiple shadows
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_WRAP_S, GL2.GL_CLAMP_TO_EDGE);
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_WRAP_T, GL2.GL_CLAMP_TO_EDGE);
// prevents (or expects!!!) pixel-y textures
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_NEAREST);
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MAG_FILTER, GL2.GL_NEAREST);
// store one value in all four components of pixel
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_DEPTH_TEXTURE_MODE, GL2.GL_INTENSITY);
Display (1st pass, for shadows):
// render shadows
gl.glUseProgram(shadowProgram);
gl.glUniformMatrix4fv(lightMatrixLocShadow, 1, false, lightMatrix.getMatrix(), 0); // yep (haha change viewMatrix -> lightMatrix)
gl.glUniformMatrix4fv(projMatrixLocShadow, 1, false, projMatrix.getMatrix(), 0);
gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, sha.frameBuffer);
gl.glViewport(0, 0, 1024, 1024);
gl.glClear(GL2.GL_DEPTH_BUFFER_BIT);
renderScene(gl, sunMatrix);
gl.glCopyTexImage2D(GL2.GL_TEXTURE_2D, 0, GL2.GL_DEPTH_COMPONENT, 0, 0, 1024, 1024, 0);
gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, 0);
Display (2nd pass, for rendering the scene):
// render display (regular)
gl.glUseProgram(displayProgram);
gl.glDrawBuffer(GL2.GL_FRONT);
gl.glReadBuffer(GL2.GL_FRONT);
gl.glUniformMatrix4fv(viewMatrixLoc, 1, false, viewMatrix.getMatrix(), 0);
gl.glUniformMatrix4fv(projMatrixLocDisplay, 1, false, projMatrix.getMatrix(), 0);
gl.glUniformMatrix4fv(lightMatrixLocDisplay, 1, false, lightMatrix.getMatrix(), 0);
gl.glUniform4fv(sunPositionLoc, 1, sunWorldPosition, 0); // send sun's position to shader
gl.glUniform1f(sunBrightnessLoc, sunBrightness);
gl.glUniform1i(shadowMapLoc, 0);
gl.glViewport(0, 0, screenWidth, screenHeight);
// day-night cycle
float[] color = SkyManager.getSkyColor(time);
gl.glClearColor(color[0], color[1], color[2], 1);
gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);
gl.glActiveTexture(GL2.GL_TEXTURE0);
gl.glBindTexture(GL2.GL_TEXTURE_2D, sha.shadowMap);
renderScene(gl, sunMatrix);
Another strange outcome is that only fragments on the z=0 plane relative to the light matrix (the light's rotating, and the plane rotates with it) are lit. All other fragments, behind and in front of the light, are shadowed.
One issue was with the line gl.glBindTexture(GL2.GL_TEXTURE, shadowMap);
I was binding the texture to GL_TEXTURE instead of GL_TEXTURE_2D.
I'm new to opencv's svm's. I tried a sample classifier but it only returns 0 as the predicted label. I even used the value 5 for training as well as the prediction.
I've been changing the values for about a hundred times but i just don't get what's wrong. I'm using OpenCV 3.0 with Java. Here's my code:
Mat labels = new Mat(new Size(1,4),CvType.CV_32SC1);
labels.put(0, 0, 1);
labels.put(1, 0, 1);
labels.put(2, 0, 1);
labels.put(3, 0, 0);
Mat data = new Mat(new Size(1,4),CvType.CV_32FC1);
data.put(0, 0, 5);
data.put(1, 0, 2);
data.put(2, 0, 3);
data.put(3, 0, 8);
Mat testSamples = new Mat(new Size(1,1),CvType.CV_32FC1);
testSamples.put(0,0,5);
SVM svm = SVM.create();
TermCriteria criteria = new TermCriteria(TermCriteria.EPS + TermCriteria.MAX_ITER,100,0.1);
svm.setKernel(SVM.LINEAR);
svm.setType(SVM.C_SVC);
svm.setGamma(0.5);
svm.setNu(0.5);
svm.setC(1);
svm.setTermCriteria(criteria);
//data is N x 64 trained data Mat , labels is N x 1 label Mat with integer values;
svm.train(data, Ml.ROW_SAMPLE, labels);
Mat results = new Mat();
int predictedClass = (int) svm.predict(testSamples, results, 0);
Even if i change the lables to 1 and 2, I still get 0.0 as a response. So something has to be absolutely wrong... I just don't know what to do. Please help! :)
I had a similar problem in C++. I'm not too sure if it's the same in Java but in C++ the predictions were saved in the results Matrix instead of returned as a float.
I'm trying to capture all the pen data: touch, pressure at one point, coordinates of the touch ...
Any suggestions?
SigCtl sigCtl = new SigCtl();
DynamicCapture dc = new DynamicCapture();
int rc = dc.capture(sigCtl, "who", "why", null, null);
if(rc == 0) {
System.out.println("signature captured successfully");
String fileName = "sig1.png";
SigObj sig = sigCtl.signature();
sig.extraData("AdditionalData", "CaptureImage.java Additional Data");
int flags = SigObj.outputFilename | SigObj.color32BPP | SigObj.encodeData;
sig.renderBitmap(fileName, 200, 150, "image/png", 0.5f, 0xff0000, 0xffffff, 0.0f, 0.0f, flags );
}
I managed to solve the problem using the wgssStu library, this jar there is PenData class, which has the following methods: getPressure, getX, getY, getRdy, getSw...
I am having an issue with a ScrolledForm. I am trying to change the background and foreground colour for a Label defined in the body of the ScrolledForm, however it doesn't seem to be working.
In my code snippet, I would like lblWhat to have a black background and white foreground.
Here is my code snippet:
ScrolledForm scrldfrmNewScrolledform = formToolkit.createScrolledForm(parent);
scrldfrmNewScrolledform.setLayoutData(gd);
scrldfrmNewScrolledform.setFont(SWTResourceManager.getFont("Segoe UI", 16, SWT.NORMAL));
scrldfrmNewScrolledform.setBackground(SWTResourceManager.getColor(SWT.COLOR_WIDGET_BACKGROUND));
scrldfrmNewScrolledform.getBody().setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
scrldfrmNewScrolledform.setImage(SWTResourceManager.getImage(EPRForm.class, "/icons/AFCCEPR.png"));
scrldfrmNewScrolledform.setBounds(10, 10, 430, 280);
formToolkit.paintBordersFor(scrldfrmNewScrolledform);
scrldfrmNewScrolledform.setText("ePR (electronic Purchase Request)");
Label lblName = new Label(scrldfrmNewScrolledform.getBody(), SWT.NONE);
lblName.setBounds(10, 21, 55, 15);
formToolkit.adapt(lblName, true, true);
lblName.setText("Name:");
text = new Text(scrldfrmNewScrolledform.getBody(), SWT.BORDER);
text.setBounds(71, 15, 269, 21);
formToolkit.adapt(text, true, true);
Label lblWhat = new Label(scrldfrmNewScrolledform.getBody(), SWT.None);
lblWhat.setBounds(10, 35, 100, 15);
lblWhat.setBackground(SWTResourceManager.getColor(SWT.COLOR_BLACK));
lblWhat.setForeground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
formToolkit.adapt(lblWhat, true, true);
lblWhat.setText("What do you want?");
Label lblItem = new Label(scrldfrmNewScrolledform.getBody(), SWT.None);
lblItem.setBounds(10, 55, 100, 15);
formToolkit.adapt(lblItem, true, true);
lblItem.setText("Items to be Ordered*");
txtItems = new Text(scrldfrmNewScrolledform.getBody(), SWT.BORDER | SWT.WRAP | SWT.H_SCROLL | SWT.V_SCROLL | SWT.CANCEL);
txtItems.setBounds(10, 60, 338, 84);
formToolkit.adapt(txtItems, true, true);
You seem to be using FormToolkit. The FormToolkit.adapt method forces the control colors to the colors set for the form (normally white background and black text).
For a single control you could try calling setBackground and setForeground after the adapt call.
You can set the colors for the entire form with
FormColors colors = toolkit.getColors();
colors.setBackground(...);
colors.setForeground(...);