Java-Gaming.org    
Featured games (91)
games approved by the League of Dukes
Games in Showcase (576)
games submitted by our members
Games in WIP (498)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  LWJGL Tutorial Series - Texturing Models  (Read 5151 times)
0 Members and 1 Guest are viewing this topic.
Offline SHC
« Posted 2013-10-24 17:30:14 »

LWJGL Tutorial Series - Texturing Models


Welcome to the sixteenth part of the LWJGL Tutorial Series. In this tutorial, we will be learning how to texture models in blender and rendering them in our program. If you've found any mistakes, please notify them to me with comments and I'll correct them. So first we need to create the textured model in Blender.

Creating a Textured Cube


Since it'll take large space to write how to create them, I've made a video that shows you how to create the model in blender.

<a href="http://www.youtube.com/v/POWq9aeDLls?version=3&amp;hl=en_US&amp;start=" target="_blank">http://www.youtube.com/v/POWq9aeDLls?version=3&amp;hl=en_US&amp;start=</a>

I only showed changing the texture coordinates on one side. If you want it to appear correctly on every side, change it to how you feel like. Now it's time for us to change our
Model
class to load textured models. Before explaining the loading code, let me explain the commands of the OBJ and MTL files which I've skipped earlier.

Parsing Textured Models


I'm not going to explain again what OBJ and MTL files are since I've covered them in the previous tutorials. Now I'll just say the format and also how to parse them. Also you have to create the necessary getters and setters by yourself since listing them can a waste of space. First, let's start with the OBJ file. In this file, now comes another command called
vt x y
which says the texture coordinate. So we add this else-if-statement to the loading method.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
else if (line.startsWith("vt "))
{
    // Split the line
   String[] values = line.split(" ");

    // Parse the values
   float x = Float.parseFloat(values[1]);
    float y = Float.parseFloat(values[2]);

    // Create the texCoord
   Vector2f texCoord = new Vector2f(x, y);
    m.getTextureCoords().add(texCoord);

    m.isTextured = true;
}

This creates a texture coordinate and adds it to the list of texture coordinates in the model. You can also see a boolean called
isTextured
which is used as a flag to differentiate the models with texture information with the ones that doesn't. This is also used to prepare the VBOs and also in the render logic. The next thing is the change in the syntax of the face command. In the previous tutorial, I didn't explain the full syntax, so here it is.

1  
2  
3  
4  
5  
6  
7  
8  
# ONLY VERTICES
f v1 v2 v3
# VERTICES AND TEX COORDS
f v1/vt1 v2/vt2 v3/vt3
# VERTICES AND NORMALS
f v1//vn1 v2//vn2 v3//vn3
# VERTICES, TEX COORDS AND NORMALS
f v1/vt1/vn1 v2/vt2/vn2 v3/vt3/vn3

In the previous article, we've implemented the face parsing for the vertices and normals and now, we need to add parsing for the texture coords as well. So we'll change the code inside the else-if clause for the face command to this. All this will be easily understood if you've read the previous tutorial and have an understanding of the format.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
else if (line.startsWith("f "))
{
    // Split the line
   String[] values = line.split(" ");

    // Parse the vertex indices
   float v1 = Float.parseFloat(values[1].split("/")[0]);
    float v2 = Float.parseFloat(values[2].split("/")[0]);
    float v3 = Float.parseFloat(values[3].split("/")[0]);

    // Create the vertex
   Vector3f vertex = new Vector3f(v1, v2, v3);

    // Parse the normal indices
   float vn1 = Float.parseFloat(values[1].split("/")[2]);
    float vn2 = Float.parseFloat(values[2].split("/")[2]);
    float vn3 = Float.parseFloat(values[3].split("/")[2]);

    // Create the normal
   Vector3f normal = new Vector3f(vn1, vn2, vn3);

    if (m.isTextured)
    {
        // Parse the texture indices
       float vt1 = Float.parseFloat(values[1].split("/")[1]);
        float vt2 = Float.parseFloat(values[2].split("/")[1]);
        float vt3 = Float.parseFloat(values[3].split("/")[1]);

        Vector3f texCoords = new Vector3f(vt1, vt2, vt3);

        // Create the face
       m.getFaces().add(new Face(vertex, normal, texCoords, material));
    }
    else
    {
        // Create the face
       m.getFaces().add(new Face(vertex, normal, null, material));
    }
}

Ah! Large listing of code. The code is modified as such that it only creates a face with texture coords if atleast one texture coord is present in the file. It gives an error saying that there is no such constructor for the class
Face
so change the existing constructor to take another
Vector3f
for the indices of the texture coords of that face. Now it's time to change the
parseMaterial()
method.

Changing the parseMaterial method


All we have to change in the
parseMaterial()
method is that the addition of loading textures. Though each material can have a texture (more textures to be precise) we will use a single texture for the entire model. This also saves memory as we use a single texture and change the appropriate texture coordinates to make it look like it has used multiple textures. So I created a texture variable in the Model class. So now add this else-if clause to it.

1  
2  
3  
4  
5  
else if (line.startsWith("map_Kd "))
{
    // Load the texture.
   m.setTexture(Texture.loadTexture("resources/textures/" + line.replaceAll("map_Kd", "").trim()));
}

This loads the texture and sets it as the texture of the model. Now it's time to change the code to create the VBOs.

Change the prepareVBO method


In the
prepareVBO
method, we need to add the code that creates a VBO for the texture coordinates. It's fairly simple, add the following code to that method inside the iteration over each face.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
if (isTextured)
{
    // Get the first texCoords of the face
   Vector2f t1 = texCoords.get((int) face.getTexCoord().x - 1);
    textureBuffer.put(t1.x).put(1 - t1.y);

    // Get the second texCoords of the face
   Vector2f t2 = texCoords.get((int) face.getTexCoord().y - 1);
    textureBuffer.put(t2.x).put(1 - t2.y);

    // Get the third texCoords of the face
   Vector2f t3 = texCoords.get((int) face.getTexCoord().z - 1);
    textureBuffer.put(t3.x).put(1 - t3.y);
}

So why are we reversing the y-coordinates? This is because Blender's system of texture coordinates is different from the standard OpenGL system of texture coordinates. Here's an image showing how the coordinate systems differ.


For this change in the systems, the textures appears inverted in OpenGL but it appears right in the Blender. So we invert the y coordinates to get the right non-inverted texture in OpenGL.

Changing the render method


All we need to change in the render code is to bind the texture coord buffer if the model is textured. So add these to the code before the call to
glDrawArrays()


1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
if (isTextured)
{
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, texture.id);

    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    // Bind the texture buffer
   glBindBuffer(GL_ARRAY_BUFFER, vboTextureID);
    glTexCoordPointer(2, GL_FLOAT, 0, 0);
}

This code binds the texture of the model, enables the texture coord array and binds the texture vbo and sets the pointer. There is nothing else to explain in this code. And finally, we need to disable the client states so at the end of that method add these lines too.

1  
2  
3  
4  
if (isTextured)
{
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}

I don't think there's anything to explain in this piece of code. If you are reading from the previous tutorials, you should be knowing it. If not, refer to the VBO tutorial. That's it to the rendering. And now, there is one thing more. You need to edit the shaders so that they apply the textures.

Using Shaders for Texturing


Texturing is also called as Texture Sampling. What you do is we send the texture data with another type of glsl, the
sampler2D
type. So at first we need to understand what
sampler2D
actually is. In GLSL 1.2, it is defined as a uniform variable that is used to hold the texture data. And GLSL is also having some attributes that gets set when using the
glTexCoordPointer()
function. So here's a listing of them.

1  
2  
3  
4  
5  
6  
7  
8  
attribute vec4 gl_MultiTexCoord0;
attribute vec4 gl_MultiTexCoord1;
attribute vec4 gl_MultiTexCoord2;
attribute vec4 gl_MultiTexCoord3;
attribute vec4 gl_MultiTexCoord4;
attribute vec4 gl_MultiTexCoord5;
attribute vec4 gl_MultiTexCoord6;
attribute vec4 gl_MultiTexCoord7;

Each of this references a texture coord unit, and this provides you to use multiple textures. There is also a built-in varying vec4 array called as
gl_TexCoord[]
. In our vertex shader, we need to copy the texcoord to that array. So we define our vertex shader like this. Note that I've omitted the lighting for simplicity.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
// The Vertex Color
varying vec4 vColor;

// The view matrix
uniform mat4 mView;
// The projection matrix
uniform mat4 mProjection;
// The normal matrix
uniform mat4 mNormal;

void main()
{
    // Pass the color to the fragment shader
   vColor = gl_Color;
   
    // Pass the texture coords
   gl_TexCoord[0] = gl_MultiTexCoord0;
   
    // Calculate the transformed vertex
   gl_Position = mProjection * mView * gl_Vertex;
}

This completes the vertex shader and in it, before the calculation of transformed vertex, we copy the texture coord to the array. We are now going to write the fragment shader. The fragment shader begins with the declaration of the sampler and ends with combining the color of texture and the vertex color. So here is the code.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
// The color of the vertex
varying vec4 vColor;

// The texture
uniform sampler2D texture;

void main()
{
    // Calculate the texture color
   vec4 texColor = texture2D(texture, gl_TexCoord[0].st);
   
    // Combine the texture color and the vertex color
   gl_FragColor = vec4(texColor.rgb * vColor.rgb, texColor.a * vColor.a);
}

What this shader does is fairly simple. We use the
texture2D
function to get the appropriate color of the texture at the texture coordinate. Here we use swizzling to only pass a vec2 with x and y since our textures are two dimensional. Then we combine the color of the texture and vertex to get it look nice. The same can be added to lighting as well but I'm omitting that in this tutorial for simplicity. This completes the shaders and there is another thing we should do now. We need to pass the texture to the shaderprogram. This can be done with the
setUniform()
of the
ShaderProgram
we've developed in the previous tutorial.

1  
shaderProgram.setUniform("texture", model.getTexture().id);

This sets the texture used by the sampler by the id of the texture that is binded. And now if you run it, you can see


That's the end of this tutorial and if you've found any mistakes in it, please notify them to me with comments. In the next tutorial, let's create a 3D room.

Source Code


Tutorial16.java
shader.frag
shader.vert
Model.java
Material.java
Face.java

Offline Stoofus

Senior Newbie





« Reply #1 - Posted 2014-01-27 21:02:43 »

I do need some help on this one.

I can't seem to get the following to work:

1  
2  
        shaderProgram.setUniform( "lightPos", camera.getPosition() );
        shaderProgram.setUniform( "texture", model.getTexture().id );


The call to model.getTexture().id does not work, with an error of: Vector3f cannot be converted to Matrix4f. The same for camera.getPosition(). I understand that the program / compiler cannot convert a Vector3f to a Matrix4f but I went through the tutorial a few times and did not see where in the code that this happens.

When I do try to run it, I get the following error:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
Exception in thread "AWT-EventQueue-0" org.lwjgl.opengl.OpenGLException: Invalid enum (1280)
   at org.lwjgl.opengl.Util.checkGLError(Util.java:59)
   at org.lwjgl.opengl.GL11.glCullFace(GL11.java:763)
   at worldofadventure.Game.initGame(Game.java:161)
   at worldofadventure.Game.gameLoop(Game.java:112)
   at worldofadventure.Game.<init>(Game.java:86)
   at worldofadventure.mainGUI.btnStartGameActionPerformed(mainGUI.java:502)
   at worldofadventure.mainGUI.access$1100(mainGUI.java:22)
   at worldofadventure.mainGUI$12.actionPerformed(mainGUI.java:296)
   at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
   at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341)
   at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
   at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
   at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
   at java.awt.Component.processMouseEvent(Component.java:6505)
   at javax.swing.JComponent.processMouseEvent(JComponent.java:3320)
   at java.awt.Component.processEvent(Component.java:6270)
   at java.awt.Container.processEvent(Container.java:2229)
   at java.awt.Component.dispatchEventImpl(Component.java:4861)
   at java.awt.Container.dispatchEventImpl(Container.java:2287)
   at java.awt.Component.dispatchEvent(Component.java:4687)
   at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
   at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4492)
   at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
   at java.awt.Container.dispatchEventImpl(Container.java:2273)
   at java.awt.Window.dispatchEventImpl(Window.java:2719)
   at java.awt.Component.dispatchEvent(Component.java:4687)
   at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:735)
   at java.awt.EventQueue.access$200(EventQueue.java:103)
   at java.awt.EventQueue$3.run(EventQueue.java:694)
   at java.awt.EventQueue$3.run(EventQueue.java:692)
   at java.security.AccessController.doPrivileged(Native Method)
   at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
   at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
   at java.awt.EventQueue$4.run(EventQueue.java:708)
   at java.awt.EventQueue$4.run(EventQueue.java:706)
   at java.security.AccessController.doPrivileged(Native Method)
   at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
   at java.awt.EventQueue.dispatchEvent(EventQueue.java:705)
   at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
   at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
   at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
   at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
   at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
   at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
BUILD STOPPED (total time: 6 seconds)


Any ideas? I can paste more code if needed.

Thanks!

-Stoofus
Offline Kefwar

Junior Member


Medals: 1



« Reply #2 - Posted 2014-01-27 21:18:48 »

Go to your ShaderProgram class and add the following methods if they don't exist:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
    public void setUniform(String name, Matrix4f value)
    {
        glUniformMatrix4(glGetUniformLocation(programID, name), false, MatrixUtil.toFloatBuffer(value));
    }

    public void setUniform(String name, Vector3f value)
    {
        glUniform3f(glGetUniformLocation(programID, name), value.x, value.y, value.z);
    }

    public void setUniform(String name, float value)
    {
        glUniform1f(glGetUniformLocation(programID, name), value);
    }
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Stoofus

Senior Newbie





« Reply #3 - Posted 2014-01-27 21:23:35 »

I was missing the last two methods, added them and the error in the IDE went away. Went to compile and received the same error. Thank you for your answer, I am getting closer at understanding! Smiley

Below is my code for ShaderProgram.java
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
125  
126  
127  
128  
129  
130  
131  
132  
133  
134  
135  
136  
137  
138  
139  
140  
141  
142  
143  
144  
145  
146  
147  
148  
149  
150  
151  
152  
153  
154  
155  
156  
157  
158  
159  
160  
161  
162  
163  
164  
165  
166  
167  
168  
169  
170  
171  
172  
173  
174  
175  
176  
177  
178  
179  
/*
Application: World Of Adventure
Use: An Adventure Game starring - YOU!

File: ShaderProgram.java
File use: To load and use Vertex and Fragment shaders

Code: Jeremiah Killoran aka Stoofus
*/



package worldofadventure;

/**
 *
 * @author Sri Harsha Chilakapati with specific modifications by Stoofus
 */


// Start import section
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL20.*;
import org.lwjgl.util.vector.Matrix4f;
import org.lwjgl.util.vector.Vector3f;
// End import section

// Start class ShaderProgram
public class ShaderProgram
{
    // Start variables
   int programID; // Program ID
   int vertexShaderID; // Vertex Shader ID
   int fragmentShaderID; // Fragment Shader ID
   // End variables
   
    // Create new ShaderProgram
   public ShaderProgram()
    {
        programID = glCreateProgram();
    }
   
    /**
     * Attach a Vertex Shader to this program
     * @param name The file name of the vertex shader
     */

   
    public void attachVertexShader( String name )
    {
        // Load the source
       String vertexShaderSource = FileUtil.readFromFile( name );
       
        // Create the shader and set the source
       vertexShaderID = glCreateShader( GL_VERTEX_SHADER );
        glShaderSource( vertexShaderID, vertexShaderSource );
       
        // Compile the shader
       glCompileShader( vertexShaderID );
       
        // Check for errors
       if( glGetShaderi( vertexShaderID, GL_COMPILE_STATUS ) == GL_FALSE )
        {
            System.err.println( "Unable to create vertex shader:" );
            // Print log
           System.err.println(glGetShaderInfoLog(vertexShaderID, glGetShaderi(vertexShaderID, GL_INFO_LOG_LENGTH)));
            dispose();
            Game.endGame();
        }
       
        // Attach the shader
       glAttachShader( programID, vertexShaderID );
    }
   
    /**
     * Attach a Fragment Shader to this program
     * @param name The file name of the Fragment Shader
     */

   
    public void attachFragmentShader( String name )
    {
        // Read the source
       String fragmentShaderSource = FileUtil.readFromFile( name );
       
        // Create the shader and set the source
       fragmentShaderID = glCreateShader( GL_FRAGMENT_SHADER );
        glShaderSource( fragmentShaderID, fragmentShaderSource );
       
        // Compile the shader
       glCompileShader( fragmentShaderID );
       
        // Check for errors
       if ( glGetShaderi( fragmentShaderID, GL_COMPILE_STATUS ) == GL_FALSE )
        {
            System.err.println( "Unable to create fragment shader:" );
            // Print log
           System.err.println(glGetShaderInfoLog(fragmentShaderID, glGetShaderi(fragmentShaderID, GL_INFO_LOG_LENGTH)));
            dispose();
            Game.endGame();
        }
       
        // Attach the shader
       glAttachShader( programID, fragmentShaderID );
    }
   
    // Start method setUniform
   public void setUniform( String name, Matrix4f value )
    {
        glUniformMatrix4( glGetUniformLocation( programID, name ), false,
                          MatrixUtil.toFloatBuffer( value ) );
       
    } // End method setUniform
   
    public void setUniform(String name, Vector3f value)
    {
        glUniform3f(glGetUniformLocation(programID, name), value.x, value.y, value.z);
    }

    public void setUniform(String name, float value)
    {
        glUniform1f(glGetUniformLocation(programID, name), value);
    }
   
    // Links this program in order to use it
   // Start method link
   public void link()
    {
        // Link this program
       glLinkProgram( programID );
       
        // Check for errors
       if ( glGetProgrami( programID, GL_LINK_STATUS ) == GL_FALSE )
        {
            System.err.println( "Unable to link shader program:");
            dispose();
            Game.endGame();
        }
    } // End method link
   
    // Bind this program in order to use it
   // Start method bind
   public void bind()
    {
        glUseProgram( programID );
    } // End method bind
   
    //Unbind the shader program
   // Starte method unbind
   public static void unbind()
    {
        glUseProgram( 0 );
    } // End method unbind
   
    // Dispose the program and shaders
   // Start method dispose
   public void dispose()
    {
        // Unbind the program
       unbind();
       
        // Detach the shaders
       glDetachShader( programID, vertexShaderID );
        glDetachShader( programID, fragmentShaderID );
       
        // Delete the shaders
       glDeleteShader( vertexShaderID );
        glDeleteShader( fragmentShaderID );
       
        // Delete the program
       glDeleteProgram( programID );
    } // End method dispose
   
    /**
     * @return The ID of this program
     */

    // Start method getID
   public int getID()
    {
        return programID;
    }
   
} // End class ShaderProgram


Below is the error:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
run:
Selected DisplayMode: 800 x 600 x 0 @0Hz
Exception in thread "AWT-EventQueue-0" org.lwjgl.opengl.OpenGLException: Invalid enum (1280)
   at org.lwjgl.opengl.Util.checkGLError(Util.java:59)
   at org.lwjgl.opengl.GL11.glCullFace(GL11.java:763)
   at worldofadventure.Game.initGame(Game.java:161)
   at worldofadventure.Game.gameLoop(Game.java:112)
   at worldofadventure.Game.<init>(Game.java:86)
   at worldofadventure.mainGUI.btnStartGameActionPerformed(mainGUI.java:502)
   at worldofadventure.mainGUI.access$1100(mainGUI.java:22)
   at worldofadventure.mainGUI$12.actionPerformed(mainGUI.java:296)
   at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
   at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341)
   at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
   at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
   at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
   at java.awt.Component.processMouseEvent(Component.java:6505)
   at javax.swing.JComponent.processMouseEvent(JComponent.java:3320)
   at java.awt.Component.processEvent(Component.java:6270)
   at java.awt.Container.processEvent(Container.java:2229)
   at java.awt.Component.dispatchEventImpl(Component.java:4861)
   at java.awt.Container.dispatchEventImpl(Container.java:2287)
   at java.awt.Component.dispatchEvent(Component.java:4687)
   at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
   at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4492)
   at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
   at java.awt.Container.dispatchEventImpl(Container.java:2273)
   at java.awt.Window.dispatchEventImpl(Window.java:2719)
   at java.awt.Component.dispatchEvent(Component.java:4687)
   at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:735)
   at java.awt.EventQueue.access$200(EventQueue.java:103)
   at java.awt.EventQueue$3.run(EventQueue.java:694)
   at java.awt.EventQueue$3.run(EventQueue.java:692)
   at java.security.AccessController.doPrivileged(Native Method)
   at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
   at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
   at java.awt.EventQueue$4.run(EventQueue.java:708)
   at java.awt.EventQueue$4.run(EventQueue.java:706)
   at java.security.AccessController.doPrivileged(Native Method)
   at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
   at java.awt.EventQueue.dispatchEvent(EventQueue.java:705)
   at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
   at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
   at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
   at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
   at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
   at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
BUILD STOPPED (total time: 8 seconds)
Offline Troubleshoots

JGO Coder


Medals: 35
Exp: 7-9 months


Damn maths.


« Reply #4 - Posted 2014-01-27 21:30:07 »

You really should learn to debug a stack trace before learning OpenGL.
By the way, I'm curious as to why you're using AWT and Swing with LWJGL...  Undecided

Why are all OpenGL tutorials written in Brainf**k?
Offline Stoofus

Senior Newbie





« Reply #5 - Posted 2014-01-27 21:36:56 »

I am familiar with stack traces, just not THAT familiar. I could trace the root of the issue but was hoping for a quicker answer. Not a big deal, as I don't mind learning from my mistakes.

As for using Swing, I am launching the display window from a GUI. Once I get everything ironed out, I should be able to replace Swing, if needed.
Offline vastrolorde

Junior Member





« Reply #6 - Posted 2014-01-28 12:12:30 »

Can anyone help me with texturing. I built the .OBJ loader with .MTL loader. Everything works fine until i have to start texturing. Textures are bugged and see through and just broken. My thread is here.http://www.java-gaming.org/topics/lwjgl-using-multiple-textures/31879/30/view.html So i thought that maybe SLick-Util texture loader is broken, so i tryed to use the one he is using in this tutorial. but now i cant get bast loading the texture. It keeps giving me
Quote
Exception in thread "main" java.lang.IllegalArgumentException: input == null!
   at javax.imageio.ImageIO.read(Unknown Source)
   at test.OBJloader.Texture.loadTexture(Texture.java:59)
   at test.OBJloader.MTLLoader.loadMaterial(MTLLoader.java:46)
   at test.OBJloader.OBJLoader.loadModel(OBJLoader.java:26)
   at controller.Controller.<init>(Controller.java:52)
   at controller.Controller.main(Controller.java:110)

Im using it on the line here.
1  
ma.texture = Texture.loadTexture("src/" + line.replaceAll("map_Kd", " ").trim());


Any ideas what might be wrong?
Offline Damocles
« Reply #7 - Posted 2014-01-28 14:17:56 »

The ImageIO.read  gets a null parameter.

 public static BufferedImage read(File input) throws IOException {
        if (input == null) {
            throw new IllegalArgumentException("input == null!");

check if you send the Parameter correctly

Test a workaround by hardcoding a new File("myPicture.png")  into
test.OBJloader.Texture.loadTexture()

I think, at that point it simply gets no valid File

Offline SHC
« Reply #8 - Posted 2014-01-28 14:30:37 »

@Stoofus

This page says that it might be a graphic driver issue.

hub.jmonkeyengine.org/forum/topic/openglexception-invalid-enum-1280/

Updating your drivers may help. I can't see any fault in code. And please use the pastebin to keep the page short.

@vastrolorde

This indicates that the texture file was not found. Did you edit the material file to change the file name to relative value? Blender creates absolute path in the file.

Offline vastrolorde

Junior Member





« Reply #9 - Posted 2014-01-28 15:39:56 »

Ok got it working. But still my textures are broken, and i dont understand what is going on. It has holes in it and it isnt showing up in some places.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline SHC
« Reply #10 - Posted 2014-01-30 05:10:04 »

@vastrolorde

Could you post a screenshot of it? I didn't understand what you've said.

Offline vastrolorde

Junior Member





« Reply #11 - Posted 2014-01-30 09:42:29 »

I have fixed the finger, but textures are still messed up.
Offline vastrolorde

Junior Member





« Reply #12 - Posted 2014-02-02 16:21:39 »

Any ideas?
Offline SHC
« Reply #13 - Posted 2014-02-03 13:52:18 »

@vastrolorde

Are you using more textures on a single model?

Offline vastrolorde

Junior Member





« Reply #14 - Posted 2014-02-03 16:34:13 »

This particular model has 2 textures, but on the screenshot is only one part of the model with one texture.
Pages: [1]
  ignore  |  Print  
 
 

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

xsi3rr4x (16 views)
2014-04-15 18:08:23

BurntPizza (14 views)
2014-04-15 03:46:01

UprightPath (27 views)
2014-04-14 17:39:50

UprightPath (12 views)
2014-04-14 17:35:47

Porlus (29 views)
2014-04-14 15:48:38

tom_mai78101 (51 views)
2014-04-10 04:04:31

BurntPizza (110 views)
2014-04-08 23:06:04

tom_mai78101 (211 views)
2014-04-05 13:34:39

trollwarrior1 (179 views)
2014-04-04 12:06:45

CJLetsGame (185 views)
2014-04-01 02:16:10
List of Learning Resources
by Longarmx
2014-04-08 03:14:44

Good Examples
by matheus23
2014-04-05 13:51:37

Good Examples
by Grunnt
2014-04-03 15:48:46

Good Examples
by Grunnt
2014-04-03 15:48:37

Good Examples
by matheus23
2014-04-01 18:40:51

Good Examples
by matheus23
2014-04-01 18:40:34

Anonymous/Local/Inner class gotchas
by Roquen
2014-03-11 15:22:30

Anonymous/Local/Inner class gotchas
by Roquen
2014-03-11 15:05:20
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!