To my immense surprise, it seems impossible to find any other people having this problem -- I can use Jmonkey to import a mesh (in my case a gear), but it doesn't properly map the texture (which is supposed to look like wood), only texturing a few select faces shown:
It still looks fine in Blender:
To summarize, how do I get the texture to map over the ENTIRE gear, not just some triangles?
My code is written like this (pardon if it's a little messy, I've been trying to solve this for a while now):
Spatial gear = assetManager.loadModel("Models/cog_3.j3o");
//Geometry geargeo=(Geometry)gear;
//Node gearnode = (Node)gear;
//Mesh gearmesh = (Mesh) gearnode;
//Mesh gearmesh = (Geometry)(gearnode.getChildren().get(0));
TangentBinormalGenerator.generate(gear);
Material wood = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
Texture woodtex = assetManager.loadTexture("Textures/wood-texture.jpg");
woodtex.setWrap(Texture.WrapMode.Repeat);
wood.getAdditionalRenderState().setFaceCullMode(RenderState.FaceCullMode.Off);
wood.setTexture("ColorMap", woodtex);
wood.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha);
gear.setMaterial(wood);
rootNode.attachChild(gear);
My mesh looks like this (you can see the uv seams):
Uv looks like this:
I'm using blender 2.78a,
and (as far as I know), the latest version of JME.
Any help is appreciated greatly.
This issue is now fixed. My shader attributes were not bound correctly.
I have got a game, which when ran from the IDE looks like this:
However, when I export it from Eclipse with these settings,
The texturing is completely incorrect. The textures are still loaded, but they are not wrapping correctly onto the object.
The code is exactly the same, as I only just exported it, and I am currently running both windows of the game at the same time(One working fine from the IDE, one looking weird from an exported JAR).
I have also copied all the resources from the IDE directory to the folder with the external JAR. IDE directory:
Directory I run the external JAR from:
Also, I know that the textures are actually loading - They are not wrapping correctly. I know this because:
If you look at the plane, you can see that it still has elements of the texture - They are just all stretched and messed up.
Same thing with the Skybox. If you look at that, parts are still there, but again, it's incorrectly wrapped around the OBJ model.
If I hit the Q key to render the terrain with a DisplayList (Wrapping the terrain texture multiple times), it shows the texture. Can't get a screenshot of this because I can't hit Q and take a screenshot.
I have checked inside the JAR file, and the fragment and the vertex shader are still there. The correct libraries also appear to be there (Besides, if they weren't, the game would not even start).
Update:
As I was restarting the game multiple times to check for more information, I noticed that as soon as the display shows (so I can see the incorrectly-textured terrain and plane), the game freezes about 90% of the time. No Stacktrace, just a "This window is not responding and windows is closing it".
The game still works perfectly without crashing when I run it in the IDE.
The server for the game exports and runs perfectly. Only the client is the issue.
What about exporting could make the game any different than running it in the IDE, and how can I solve it?
Update:
So here is my texture loading code:
loader.loadTexture("PlaneTexture", 1);
//loadTexture() method:
public int loadTexture(String fileName, int mipmap) {
Texture texture = null;
try {
try{
texture = TextureLoader.getTexture("PNG", new FileInputStream("res/" + fileName + ".png")); //TextureLoader is a Slick-Util class.
}catch (Exception e){
e.printStackTrace();
}
if (texture == null){
throw new Exception("Null texture!");
}
//texture = TextureLoader.getTexture("GIF", new FileInputStream("res/" + fileName + ".png"));
if (mipmap > -10){
GL30.glGenerateMipmap(GL11.GL_TEXTURE_2D);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR_MIPMAP_LINEAR);
GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL14.GL_TEXTURE_LOD_BIAS, mipmap);
}
} catch (Exception e) {
e.printStackTrace();
System.err.println("Tried to load texture " + fileName + ".png , didn't work");
System.exit(1);
return -1;
}
textures.add(texture.getTextureID());
return texture.getTextureID();
}
I now have the texture ID of the texture. I then render the object (in this case the plane) like this:
Plane you = Main.TerrainDemo.shipsID.get(Main.TerrainDemo.UID);
Main.TerrainDemo.shader.start();
TexturedModel texturedModel = TerrainDemo.shipModel; //The plane model
RawModel model = texturedModel.getRawModel();
GL30.glBindVertexArray(model.getVaoID());
GL20.glEnableVertexAttribArray(0);
GL20.glEnableVertexAttribArray(1);
GL20.glEnableVertexAttribArray(2);
GL13.glActiveTexture(GL13.GL_TEXTURE0);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, TerrainDemo.shipModel.getTexture().getID()); //The ID of the texture.
glDrawElements(GL_TRIANGLES, model.getVertexCount(), GL11.GL_UNSIGNED_INT, 0);
And, although I don't think they're important, my vertex and fragment shaders:
//Vertex shader
#version 130
in vec3 position;
in vec2 textureCoords;
in vec3 normal;
out vec2 pass_textureCoords;
out vec3 surfaceNormal;
out vec3 toLightVector;
uniform mat4 transformationMatrix;
uniform vec3 lightPosition;
void main(void){
gl_Position = ftransform();
pass_textureCoords = textureCoords;
surfaceNormal = (transformationMatrix * vec4(normal, 0.0)).xyz;
toLightVector = (vec3(500, 50000, 500)) - (transformationMatrix * vec4(position, 1.0)).xyz;
}
//Fragment shader
#version 130
in vec2 pass_textureCoords;
in vec3 surfaceNormal;
in vec3 toLightVector;
out vec4 out_Color;
uniform sampler2D textureSampler;
uniform vec3 lightColour;
void main(void){
vec3 unitNormal = normalize(surfaceNormal);
vec3 unitLightVector = normalize(toLightVector);
float nDot1 = dot(unitNormal, unitLightVector);
float brightness = max(nDot1, 0.2);
brightness = brightness + 0.5;
vec3 diffuse = brightness * vec3(1, 1, 1);
vec4 textureColor = vec4(diffuse, 1.0) * texture(textureSampler, pass_textureCoords);
if(textureColor.a<1){
discard;
}
out_Color = vec4(textureColor.r, textureColor.g, textureColor.b, 1);
}
Again, I will stress that all of this is working perfectly if the game is running from the IDE. It is just if it runs from an external JAR that the issue occurs.
I will be experimenting with different texture loading techniques and methods (e.g. packing textures into the JAR) and seeing if anything different happens.
Yet another update:
So, I sent the game to another person (They also use windows 8), and the game worked perfectly! No texturing errors whatsoever! So now I'm unsure if the problem is with my PC specifically or something else.
For those who wish to try, you can download the game at http://endcraft.net/PlaneGame and see it yourself (Please read the instructions.txt - Also, you'll need a program to decompress .rar files).
I will be getting as many people as I know to give the game a go and see if they have the same issue or if the texturing is correct.
It is completely baffling me that it works fine when I run it from the IDE, but does not work when I export into an external jar, but does work when I export it into an external jar and send it to someone else!
(another) Update:
I have sent the game to multiple people, some of them are coming across this crash:
# A fatal error has been detected by the Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x1cd6b57f, pid=36828, tid=35556
#
# JRE version: Java(TM) SE Runtime Environment (8.0_31-b13) (build 1.8.0_31-b13)
# Java VM: Java HotSpot(TM) Client VM (25.31-b07 mixed mode windows-x86 )
# Problematic frame:
# C [atioglxx.dll+0xc0b57f]
#
In the log file, I see this:
Stack: [0x011d0000,0x01220000], sp=0x0121f1e8, free space=316k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C [atioglxx.dll+0xc0b57f]
C [atioglxx.dll+0xbe8b95]
C [atioglxx.dll+0x641852]
C [lwjgl.dll+0x9a28]
j org.lwjgl.opengl.GL20.glUniformMatrix4(IZLjava/nio/FloatBuffer;)V+33
j TMLoading.ShaderProgram.loadMatrix(ILorg/lwjgl/util/vector/Matrix4f;)V+23j
TMLoading.StaticShader.loadTransformationMatrix(Lorg/lwjgl/util/vector/Matrix4f;) V+6
j Joehot200.Plane.render()V+407
j Joehot200.TerrainDemo.render()V+4045
j Joehot200.TerrainDemo.enterGameLoop()V+356
j Joehot200.TerrainDemo.startGame()V+320
j StartScreenExperiments.Test2.resartTDemo()V+128
j StartScreenExperiments.Test2.main([Ljava/lang/String;)V+27
v ~StubRoutines::call_stub
V [jvm.dll+0x1473e5]
In other words, the entire issue (the texturing and the crashes) are beginning to look a lot like they are related to the shaders (either parsing information to them, or the actual shader code itself).
I have also done more testing, and the texturing works fine without shaders using a DisplayList.
Here is the code up to the glUniformMatrix() call:
//Some unnecessary code has been removed. For example, you do not care about what colour I make the plane depending on what team it is on.
//Plane class. (Referring to a jet plane which is the main object the player controls)
public void render(){
twodcoords = TextDemo.getScreenCoords(sx, sy + 30, sz);
glPushAttrib(GL_ENABLE_BIT);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glPushMatrix();
glTranslatef(sx, sy, sz);
GL30.glBindVertexArray(Main.TerrainDemo.vaoID);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glRotatef(srot, 0f, 1f, 0f);
glRotatef(pitch, -1f, 0f, 0f);
Main.TerrainDemo.shader.start();
glPushMatrix();
glDisable(GL_LIGHTING);
TexturedModel texturedModel = TerrainDemo.shipModel;
RawModel model = texturedModel.getRawModel();
GL30.glBindVertexArray(model.getVaoID());
GL20.glEnableVertexAttribArray(0);
GL20.glEnableVertexAttribArray(1);
GL20.glEnableVertexAttribArray(2);
GL13.glActiveTexture(GL13.GL_TEXTURE0);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, TerrainDemo.shipModel.getTexture().getID());
org.lwjgl.util.vector.Matrix4f m = Assist.createTransformationMatrix(new Vector3f(sx, sy, sz), new Vector3f(pitch, rot, roll), new Vector3f(5, 5, 5)); //Creates a transformation matrix based on the X, Y, Z, Pitch, yaw, roll, and scale of the plane.
Main.TerrainDemo.shader.loadTransformationMatrix(m);
glDrawElements(GL_TRIANGLES, model.getVertexCount(), GL11.GL_UNSIGNED_INT, 0);
GL20.glDisableVertexAttribArray(0);
GL20.glDisableVertexAttribArray(1);
GL20.glDisableVertexAttribArray(2);
GL30.glBindVertexArray(0);
GL30.glBindVertexArray(0);
glPopMatrix();
glPopAttrib();
}
//StaticShader class. This method literally just passes it to the loadMatrix class.
public void loadTransformationMatrix(Matrix4f matrix){
super.loadMatrix(location_transformationMatrix, matrix);
}
//ShaderProgram class.
FloatBuffer buf = BufferUtils.createFloatBuffer(4 * 4);
public void loadMatrix(int location, Matrix4f matrix){
matrix.store(buf);
buf.flip();
GL20.glUniformMatrix4(location, false, buf);
}
Update - So, with one hour left on the Bounty, I thought I'd add a few more details:
As I probably said somewhere above, the game works for some when exported, but not for others. I've noticed that the game has always worked when ran on java 7, but with me only me and one other tester on java 7, this really isn't conclusive.
The texturing renders correctly in a DisplayList. The textures are loading. However, they are not being displayed correctly.
Even if you don't know the problem, trying out the game (ignore the start screen, I need to make a new one) and telling me the results, as well as your OS/Java details, etc, would be really appreciated.
Yes, the mipmapping is correct. I know someone in the comments mentioned it possibly wasn't, but I've tried setting it stupidly high and I do indeed get a very blurred texture.
I've already tried "package libraries into external jar". I appreciate the time taken for that answer, but I did say in the comments that I've already tried it.
The issue may be the fragment shader (as someone suggested in the comments), but I am currently unsure how to test it, nor do I understand why it would work inside the IDE but not outside of it.
I can't test this, so I'm not sure if this will help, but some implementations of OpenGL don't save element buffers in VAOs. So try binding the element buffer before the call to glDrawElements, e.g.
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, someBuffer);
glDrawElements(GL_TRIANGLES, model.getVertexCount(), GL11.GL_UNSIGNED_INT, 0);
If you don't do this, you may be using the last bound buffer for all draw calls. Probably not the answer, but it couldn't hurt to test it. I also noticed that you are using an older version of Slick, as you still have the slick-util, which is not part of the latest release, so you could also try updating that.
So try this instead of Extracting the required libraries try Package option instead, Because i personally believe there is an issue while finding those library files or linking some file then simply run the package.
I have a mesh generated from data in Renderables. Environment is set. Material is a simple new Material().
... /*init renderable*/
/*set mesh parameters*/
renderable.mesh = new Mesh(false,
(int)(meshVertexArray.length/SurfaceBuilder.__ELEMENTSPERVERTEX__), /*!vertices, not cordinates*/
meshIndexArray.length,
new VertexAttribute(Usage.Position,3,"a_position"),
new VertexAttribute(Usage.Normal,3,"a_normal"),
new VertexAttribute(Usage.TextureCoordinates,2,"a_texCoords"),
new VertexAttribute(Usage.ColorPacked,4, "a_color")
);
... /*set vertices*/
The mesh is generated properly, but I can't see the textures, only the gray (shaded) triangles. I did try the rtfm method, but so far I saw no way to bind a texture, so it displays properly in libGDX, only with shaders, and I'm not using them (I'm catching up on them after this feature is implemented). Is there a way in libGDX to bind textures to a mesh without shaders?
Without seeing your texturing code, maybe try specify a texture for your material using the following format:
Material mat = new Material();
//set the diffuse channel on the texture using some texture
mat.set(TextureAttribute.createDiffuse(new Texture("crate.jpg")));
I have a problem with OrgXML and JMonkeyEngine. I created a model in blender. After that I exported it into OrgXML format. And I got few files with extensions: mash.xml, scene, materials and some textures in jpg. I was reading the tutorial from JMonkey site and there is an example on that site:
// Load a model from test_data (OgreXML + material + texture)
Spatial ninja = assetManager.loadModel("Models/Ninja/Ninja.mesh.xml");
ninja.scale(0.05f, 0.05f, 0.05f);
ninja.rotate(0.0f, -3.0f, 0.0f);
ninja.setLocalTranslation(0.0f, -5.0f, -2.0f);
rootNode.attachChild(ninja);
// You must add a directional light to make the model visible!
DirectionalLight sun = new DirectionalLight();
sun.setDirection(new Vector3f(-0.1f, -0.7f, -1.0f).normalizeLocal());
rootNode.addLight(sun);
This is correct for this example. I have a beautifull ninja in Eclipse. But when I try do the same with my model, it doesn't work correctly. I have a red sword (which I created) in space, there aren't any textures. I created assets folder in my project directory, and subfolders "Models" and "Sword". In "Sword" directory I have all files which were exported from blender. Anybody know what I'm going wrong?
There's a bunch of stuff I would try.
First you probably want to figure out if it's an export problem in Blender or import problem in jmonkey.
Open the .mesh.xml files and see if there's a bunch of coordinates inside.
Second try importing the .scene with the asset manager instead of .mesh.xml.
Third, try to convert the .scene to a .j3o file by right clicking on it.
I'm a new jmonkey user an am trying to figure all this stuff out too.
I have a java 3d application and this application I load an OBJ file into my scene. How can I assign a texture (a jpg file) to this model?
To be more precise, when I want to assign texture to a primitive java object (e.g. sphere) I use the following:
Sphere sphere = new Sphere(Radius, Primflags, Appearance);
However, when loading and adding an obj file I do:
Scene scene = getSceneFromFile("OBJ file");
myBranchGroup = scene.getSceneGroup();
And in second case, I can find no way of assigning the texture. How should I do that?
You would have to use a program that you made the obj file or were you can load the file. Paint it, then export that file. Then add this code to it outside any methods
static TextureLoader loader = new TextureLoader("C:\\Users\\Sawyera\\Desktop\\Paint Layer 1.jpg",
"RGP", new Container());
static Texture texture = loader.getTexture();
Then
texture.setBoundaryModeS(Texture.WRAP);
texture.setBoundaryModeT(Texture.WRAP);
texture.setBoundaryColor(new Color4f(0.0f, 1.0f, 0.0f, 0.0f));
TextureAttributes texAttr = new TextureAttributes();
texAttr.setTextureMode(TextureAttributes.MODULATE);
Appearance ap = new Appearance();
ap.setTexture(texture);
ap.setTextureAttributes(texAttr);
int primflags = Primitive.GENERATE_NORMALS
+ Primitive.GENERATE_TEXTURE_COORDS;
ObjectFile loader = new ObjectFile(ObjectFile.RESIZE);
Then add this before you assign the model to the scene. Assuming the 3D model varrible is called model
model.setAppearance(ap);
IIRC you need to get the Shape3D node you want to apply the texture to (calling setAppearance(...)) from your branch group, e.g. by using getChild(index) etc. Note that you might to iterate recursively through the children, since the branch group you get might actually contain other groups, so you might find the shapes further down the group tree.
Alternatively you should be able to add an AlternateAppearance object to the branch group.