Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (487)
Games in Android Showcase (112)
games submitted by our members
Games in WIP (553)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1] 2
  ignore  |  Print  
  color coded picking  (Read 6598 times)
0 Members and 1 Guest are viewing this topic.
Offline Wizumwalt

Junior Member




Java games rock!


« Posted 2006-04-27 23:21:09 »

I'm going to give color coding a try but can't find any examples of this in my redbook. I have a few questions relating to the code below. Basically, I'm still trying to solve being able to highlight each individual triangle as the mouse hovers over it.

Previous ideas on how to do this ... frame rendering loop:
1. clear depth/color-buffer
    ... I do this in my display
2. render color-coded
   ... I don't know what this means. How is it color-coded? Before I draw the triangle, all I do is choose a unique color?
3. read color of pixel of mouse w/ glReadPixel()
4. clear depth/color buffer
   ... Is all the above done in SELECT render mode?
5. render model.
   ... And then I switch to RENDER mode here?

My stuff looks like this ...

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  
public void display(GLAutoDrawable drawable) {
   // ...

   switch (getRenderState()) {
      case ModelConstants.UPDATE: // RENDER Mode
        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);

         // Projection transformation.            
        gl.glMatrixMode(GL.GL_PROJECTION);
         gl.glLoadIdentity();
         
         gl.glOrtho(-winWidth * getZoomFactor(), winWidth * getZoomFactor(),
            -winHeight * getZoomFactor(), winHeight * getZoomFactor(), 100, -100);
               
         // reset the modelview matrix
        gl.glColor3f(1.0f, 1.0f, 1.0f);
         gl.glMatrixMode(GL.GL_MODELVIEW);
         gl.glLoadIdentity();

         // Viewing transformation.
        glu.gluLookAt(centroid.getX(), centroid.getY(), centroid.getMax_Z(),
            centroid.getX(), centroid.getY(), centroid.getZ(),
            0.0, 1.0, 0.0);

         // Modeling tranformation.
        arcBall.getTransform().get(transf);
         gl.glMultMatrixf(transf);
                     
         // Draw the model.
        {
            // eventually, calls drawByRegion below
           // to draw model.
           drawModel(drawable);
         }
         
         break;

      case ModelConstants.SELECT: // SELECT Mode
        // ... handle selection and picking


Added GL_COLOR_ARRAY here.

If each triangle has its own color (all 3 vertices have the same color), doesn't that mean I need to draw by triangle using glDrawElements? I thought that's part of what color-coding would move away from to help speed things up? Just a bit confused here. This is my code where I draw my model and works fine. Uses selection on groups of elements, but not per element.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
public void drawByRegions(GL gl, int index, int activeId, Color color) {
   gl.glEnableClientState(GL.GL_VERTEX_ARRAY);
   gl.glEnableClientState(GL.GL_COLOR_ARRAY);

   // ...
  vElementsBuffer[index].rewind();

   // highlights groups of elements.  
  gl.glLoadName(index);
   gl.glVertexPointer(3, GL.GL_FLOAT, 0, vElementsBuffer[index]);
   gl.glDrawArrays(GL.GL_TRIANGLES, 0, vElementsBuffer[index].capacity() / 3);

   gl.glDisableClientState(GL.GL_VERTEX_ARRAY);
   gl.glDisableClientState(GL.GL_COLOR_ARRAY);

   return;
}

Offline pepijnve

Junior Member




Java games rock!


« Reply #1 - Posted 2006-04-28 11:23:51 »

You can use OpenGL's select render mode to do this type of selection. The general idea is that for each distinct object you place a distinct combination of integer values on the name stack. Afterwards OpenGL provides you with a set of hit records that each contain the values that were on the name stack. You can then use these values to determine which objects were selected. This is the same idea as color coded rendering, except your using stacks of integer values instead of colors. Chapter 13 of the red book explains all this quite well.
Online Riven
« League of Dukes »

JGO Overlord


Medals: 783
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #2 - Posted 2006-04-28 13:04:56 »

In his previous posts (leading up to this one) he talked about 10k - 100k poly models picked *per triangle*.

Color-coding is the only way to get decent performance out of this.

I'll reply with more useful info tonight, as I'm at work now.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline turquoise3232

Junior Member




Java (games) rock!


« Reply #3 - Posted 2006-04-28 20:07:56 »

Hi,

I don't have much time to answer your post but...
Basically you don't use select mode anymore. You draw each triangle with a single color, to do that i suggest that you use COLOR_ARRAYS as you seem to try.
But i don't see a Buffer with color information in it? When you have both vertex and color buffer you can draw the whole bunch of triangles, read the pixel under the mouse and retrieve the triangle. You certainly don' t need to draw triangle 1 by 1.

Hope it helps...
Before Riven explains more.
Online Riven
« League of Dukes »

JGO Overlord


Medals: 783
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #4 - Posted 2006-04-28 21:07:14 »

Quite right..


You have your vertices in:
FloatBuffer vertexData

You have your colors in:
ByteBuffer colorData


Imagine you have 4 triangles, each triangle occupies 9 floats (3*3d vertex) in your vertexData. To make every triangle solid shaded, each vertex of it must have the same color. So you fill your colorData with 1 color per 3 vertices, then move on to the next. To be able to quickly identify which triangle was selected, it would be nice to not have FLOAT colors, but UNSIGNED_BYTE colors, to be able to work on bit-level easily later on.

triangle 0 [color = 0,0,0]
triangle 1 [color = 0,0,1]
triangle 2 [color = 0,0,2]
triangle 255 [color = 0,0,255]
triangle 256 [color = 0,1,0]
triangle 257 [color = 0,1,1]
triangle 258 [color = 0,1,2]
etc.

Now when you read back the pixel, you'll get 3 bytes (RGB) which are quite easy to turn into the index again:
0,0,2 = (0 << 16) | (0 << 8) | (2 << 0) = 2
0,1,1 = (0 << 16) | (1 << 8) | (1 << 0) = 257
0,1,2 = (0 << 16) | (1 << 8) | (2 << 0) = 258


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  
public final void renderColorCoded()
{
   glEnable(GL_VERTEX_ARRAY);
   glEnable(GL_COLOR_ARRAY);

   glVertexPointer(3, GL_FLOAT, 0, vertexData);
   glColorPointer(3, GL_UNSIGNED_BYTE, 0, colorData);
   glDrawArrays(GL_TRIANGLES, 0, vertexData.remaining() / 3);

   glDisable(GL_COLOR_ARRAY);
   glDisable(GL_VERTEX_ARRAY);
}

public final void renderNormally()
{
   glEnable(GL_VERTEX_ARRAY);

   glVertexPointer(3, GL_FLOAT, 0, vertexData);
   glDrawArrays(GL_TRIANGLES, 0, vertexData.remaining() / 3);

   glDisable(GL_VERTEX_ARRAY);
}

public final void renderFrame()
{
   // ... clear color+depth
   renderColorCoded();

   glReadPixels(x, y, 1, 1, ...);

   // ... clear color+depth
   renderNormally();


   //
}


Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline Wizumwalt

Junior Member




Java games rock!


« Reply #5 - Posted 2006-05-01 15:54:42 »

Not sure if I'm using glReadPixels, correctly, is this the correct way to call glReadPixels() when  using the mouse to select an element? For a single pixel, the size should be 3, correct? And only the x, y of the mouse gets passed into glReadPixels x, y, width, and height? Is there a specific buffer I need to read from and use glReadBuffer()?

My app crashes the vm. If I remove glReadPixels(), my app doesn't crash.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
//constructor
MyModeler {
      mouseBuffer = BufferUtils.newByteBuffer(3);
}

// called per frame rendering within display() ...

mouseBuffer.rewind();

if (renderer.getMouseX() > 0 && renderer.getMouseY() > 0) {
       gl.glReadPixels(renderer.getMouseX(), renderer.getMouseY(),
       renderer.getMouseX(), renderer.getMouseY(),
       GL.GL_RGB, GL.GL_UNSIGNED_BYTE, mouseBuffer);
}

gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);

Offline cylab

JGO Ninja


Medals: 43



« Reply #6 - Posted 2006-05-01 16:36:26 »

Since you specified x and y coordinates for width and height, you get a returnbuffer a lot bigger than 3 bytes, which is likely the cause for your crash.

Try
1  
2  
3  
4  
5  
       gl.glReadPixels(
              renderer.getMouseX(), renderer.getMouseY(), 1, 1
              GL.GL_RGB, GL.GL_UNSIGNED_BYTE,
              mouseBuffer
       );

Mathias - I Know What [you] Did Last Summer!
Offline Wizumwalt

Junior Member




Java games rock!


« Reply #7 - Posted 2006-05-01 16:47:02 »

Ok, I understood it wrong, thanks, that fixed the crash, but it still populates my mouseBuffer with 0's immediately after the glReadPixels line. So something still isn't right.

1  
2  
3  
4  
5  
6  
   mouseBuffer.rewind();

        // outputs all 0's
  while (mouseBuffer.position() < mouseBuffer.capacity()) {
      System.out.println("mouseBuffer: " + mouseBuffer.get());  
   }

Online Riven
« League of Dukes »

JGO Overlord


Medals: 783
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #8 - Posted 2006-05-01 17:51:59 »

Take into account that the y-axis is UP (not down, like J2D)

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline Wizumwalt

Junior Member




Java games rock!


« Reply #9 - Posted 2006-05-01 18:30:18 »

Just a few more questions cause I don't see how going this route will solve my problems.

I don't think I understand. I have my y axis as up in my glLookAt() method and I update my mouse x & y on mouseMoved() so I should be getting something in my buffer w/ 1 in the width and height of glReadPixels. Sometimes I see values, but most of the time, the returne RGB is 0 even when I'm hovering over a triangle that was color coded.

Another question I have about using this color coded method is below. My code looks like this.

1  
2  
3  
4  
5  
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
draw_ColorCoded(...);
glReadPixels(...);
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
draw_Normally(...);


I still don't see how this method works for me as I can't highlight a single element visually in the model using the last method draw_Normally(...) which looks like below (and using glDrawElements ... well, I might as well return to my old methods of bad performance).

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
      gl.glEnableClientState(GL.GL_VERTEX_ARRAY);
   
      gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_LINE);
     
      vElementsBuffer[index].rewind();
     
      gl.glLoadName(index); // This loadName does selection on an entire group.
     gl.glVertexPointer(3, GL.GL_FLOAT, 0, vElementsBuffer[index]);
      gl.glDrawArrays(GL.GL_TRIANGLES, 0, vElementsBuffer[index].capacity() / 3);

      gl.glDisableClientState(GL.GL_VERTEX_ARRAY);
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Online Riven
« League of Dukes »

JGO Overlord


Medals: 783
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #10 - Posted 2006-05-01 19:48:39 »

Y-UP was meant as: the top of your screen has the highest Y value, and the bottom has 0. With your mouse it's the opposite.

So to know which pixel you need to read:
int xFramebuffer = xMouse;
int yFramebuffer = displayHeight - yMouse;


Well, just imagine you can readback the pixel this way, then you can use the RGB values to find the INDEX of the triangle - as you encoded the RGB values in such a way that you can decode them back later. Now that you have the index of the triangle, render only that one, as a last step.

Problem solved Smiley

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Online Riven
« League of Dukes »

JGO Overlord


Medals: 783
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #11 - Posted 2006-05-01 19:52:00 »

And make SURE you set the POLYGON_MODE back to FILL, as otherwise your color-picking will not work 99% of the time (as you don't fill your triangles) !!

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline turquoise3232

Junior Member




Java (games) rock!


« Reply #12 - Posted 2006-05-01 20:36:41 »

Problem solved Smiley

At last!  Cheesy
Offline Wizumwalt

Junior Member




Java games rock!


« Reply #13 - Posted 2006-05-01 21:50:00 »

Pfftt, everything is so easy for you guys!
Offline turquoise3232

Junior Member




Java (games) rock!


« Reply #14 - Posted 2006-05-02 19:10:54 »

It was just a joke, and as the wise says : "Even the longest travel starts with a small step".
Hope the color picking will solve your problem anyway... Keep us informed.
Offline Wizumwalt

Junior Member




Java games rock!


« Reply #15 - Posted 2006-05-02 20:40:04 »

Well, it's getting closer, at least now I understand what's suppose to happen. I'm just trying to implement it efficiently now.

I'm having a hard time reading the color under the pointer. For some reason, it throws exceptions like the following when I mouse over my model and I can't for anything figure why the color blue would read a -55. It does this quite a bit, throwing an exception because of blue being out of range. I've rechecked my color init method several times and the colors of my triangles RGB's are all valid between 0 - 255.

I'm betting there's a better way to do than what I've got below.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
java.lang.IllegalArgumentException: Color parameter outside of expected range: Blue
        at java.awt.Color.testColorValueRange(Color.java:285)
        at java.awt.Color.<init>(Color.java:369)
        at java.awt.Color.<init>(Color.java:344)
        at gov.nasa.jsc.renderer.Modeler.readElementColor(Modeler.java:632)
        at gov.nasa.jsc.renderer.Modeler.drawRegions(Modeler.java:185)
        at gov.nasa.jsc.renderer.Renderer.drawModel(Renderer.java:613)
        at gov.nasa.jsc.renderer.Renderer.display(Renderer.java:245)

iae, r: 0, g: 30, b: -55


1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
public void readElementColor(GLAutoDrawable drawable) {
   GL gl = drawable.getGL();

   mouseBuffer.clear();

   // getMouseY() is actually winHeight() - mouseY.
  gl.glReadPixels(renderer.getMouseX(), renderer.getMouseY(), 1, 1, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, mouseBuffer);

   mouseBuffer.rewind();

   try {
      activeColor = new Color(mouseBuffer.get(0), mouseBuffer.get(1), mouseBuffer.get(2));

      System.out.println("activeColor: " + activeColor.toString() + ", hashCode: " + activeColor.hashCode());
   }
   catch (IllegalArgumentException iae) {
      iae.printStackTrace();

      System.out.println("iae, r: " + mouseBuffer.get(0) + ", g: " +   mouseBuffer.get(1) + ", b: " + mouseBuffer.get(2));
   }

   return;
}


And then I redraw the single triangle here as a last step.
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
public void drawActiveElement(GL gl) {
   ActiveData elementData = null;

   if (colorMap.containsKey(activeColor.hashCode()) == false) {
      System.out.println("hashcode Not found.");
      return;
   }

   elementData = (ActiveData) colorMap.get(activeColor.hashCode());

   gl.glEnableClientState(GL.GL_VERTEX_ARRAY);
   
   gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL);
   gl.glColor3f(1.0f, 1.0f, 1.0f);

   gl.glVertexPointer(3, GL.GL_FLOAT, 0, elementData.getNodeBuffer());
   gl.glDrawArrays(GL.GL_TRIANGLES, 0, elementData.getNodeBuffer().capacity());

   gl.glDisableClientState(GL.GL_VERTEX_ARRAY);

   return;
}
Offline Wizumwalt

Junior Member




Java games rock!


« Reply #16 - Posted 2006-05-02 22:17:11 »

To be able to quickly identify which triangle was selected, it would be nice to not have FLOAT colors, but UNSIGNED_BYTE colors, to be able to work on bit-level easily later on.

UNSIGNED_BYTE didn't work for me, kept throwing IllegalArgumentExceptiosn when doing a call on glReadPixel, would fill my mouseBuffer w/ negative values. So I am using GL_BYTE which seems to work.

My hashCode idea for a key isn't panning out very well so I'm back to trying to understand this idea. Each 3 of my vertices for a triangle have the same RGB value. What I don't understand is how your using the index. Is that a String index value like "0,0,1" as a key to do a lookup? I store in a Hashtable a key w/ the object being the vertex array of 9 coord's for my triangle. I don't know why I can't understand glDrawElements().

triangle 0 [color = 0,0,0]
triangle 1 [color = 0,0,1]
triangle 2 [color = 0,0,2]
triangle 255 [color = 0,0,255]
triangle 256 [color = 0,1,0]
triangle 257 [color = 0,1,1]
triangle 258 [color = 0,1,2]
etc.

And of course I couldn't get this to work either.

Now when you read back the pixel, you'll get 3 bytes (RGB) which are quite easy to turn into the index again:
0,0,2 = (0 << 16) | (0 << Cool | (2 << 0) = 2
0,1,1 = (0 << 16) | (1 << Cool | (1 << 0) = 257
0,1,2 = (0 << 16) | (1 << Cool | (2 << 0) = 258

Can you help on this idea some more?

Other than these problems, I can see that my triangles are different colors and my mouse is reading them. It's just storing/indexing and redrawing that last element that's got me now.
Online Riven
« League of Dukes »

JGO Overlord


Medals: 783
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #17 - Posted 2006-05-02 22:47:05 »

Please use UNSIGNED_BYTE, you just have to convert them back through code:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
ByteBuffer mouse = ...;
glReadPixels(x,y,1,1,mouse);
int r = mouse.get() & 0xFF; // this turns the byte into an unsigned byte (using the sign-bit as the ordinary 8th bit of an int: 32bit)
int g = mouse.get() & 0xFF;
int b = mouse.get() & 0xFF;

int triangleIndex = (r << 16) | (g <<< 8) | (b << 0); // decode the RGB to Index

indices.position(triangleIndex*3);
indices.limit(triangleIndex*3 + 3);
glDrawElements(....... paint 1 triangle...., indices);

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline Wizumwalt

Junior Member




Java games rock!


« Reply #18 - Posted 2006-05-03 22:38:14 »

It's almost there. I beleive I've got this working and the performance really is much better, even though my triangles are not hightlighting properly, I can tell it functions close to what it should. I think my only problem left is that my triangles are colored wrong and I can't tell where the problem is.

From one vertex (side) of the triangle it's shaded darker/lighter and as you cross the triangle to another vertex, it gets lighter or darker. Some Triangles are all one color, but the colors of the multi-colored (shaded) triangles are all within the range that I thought I was setting my colors to.


I have a FloatBuffer triBuffer(3 * 3) per triangle that contains these coord values ...
   v1.x, v1.y, v1.z, v2.x, v2.y, v2.z, v3.x, v3.y, v3.z

I have a ByteBuffer cBuffer(3 * 4) that contains int values of R, G, or B as such ...
   v1.r, v1.g, v2.b, v2.r, v2.g, v2.b, v3.r, v3.g, v3.b


Here is where I add my colors.

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  
// stores a single triangle.
FloatBuffer triBuffer = BufferUtils.newFloatBuffer(3 * 3);

// stores colors for a single triangle.
// 3 colors and we store 32 bit ints for each color w/ putInt?
ByteBuffer cBuffer = BufferUtils.newByteBuffer(3 * 4);

for (all triangles) {
   elementBuffer[i] = BufferUtils.newFloatBuffer(region.size() * 9);

   // 1 color = 3 bytes per triangle ((3 * 3) *3).
  colorBuffer[i] = BufferUtils.newByteBuffer((region.size() * 9) * 3);

   indicesBuffer[i] = BufferUtils.newIntBuffer(region.size() * 3);


    for (each triangle) {
   int idx = 0;

   for (int i = 0; i < 3; i++) { // loop edges of a single triangle
     cBuffer.putInt(idx, getRed());
      triBuffer.put(idx++, (float) node.getX());
   
      cBuffer.putInt(idx, getGreen());
      triBuffer.put(idx++, (float) node.getY());

      cBuffer.putInt(idx, getBlue());
      triBuffer.put(idx++, (float) node.getZ());
   }

   colorBuffer[i].put(cBuffer);
   elementBuffer[i].put(triBuffer);
   indicesBuffer[i].put(index++);

   incrementColor();
    }

    i++;
}


And here I draw my color coded triangles.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
public void drawByRegions_ColorCoded(GL gl, int index, int activeId, Color color) {
   gl.glEnableClientState(GL.GL_COLOR_ARRAY);
   gl.glEnableClientState(GL.GL_VERTEX_ARRAY);

   gl.glEnable(GL.GL_CULL_FACE);
   gl.glCullFace(GL.GL_BACK);
   gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL);

   vElementsBuffer[index].rewind();
   colorBuffer[index].rewind();

   gl.glColorPointer(3, GL.GL_UNSIGNED_BYTE, 0, colorBuffer[index]);
   gl.glVertexPointer(3, GL.GL_FLOAT, 0, vElementsBuffer[index]);
   gl.glDrawArrays(GL.GL_TRIANGLES, 0, vElementsBuffer[index].capacity() / 3);

   gl.glDisable(GL.GL_CULL_FACE);
   gl.glDisableClientState(GL.GL_COLOR_ARRAY);
   gl.glDisableClientState(GL.GL_VERTEX_ARRAY);

   return;
}


Does anyone see anything wrong with what I've got there. I can't tell why my colors are not a single solid color in each triangle. BTW - I just left off doing the glClear between drawing_colorCoded() and then doing a draw_Normally() within the same frame so I could see what was going on.
Online Riven
« League of Dukes »

JGO Overlord


Medals: 783
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #19 - Posted 2006-05-04 06:39:05 »

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
for (each triangle) {
int idx = 0;

for (int i = 0; i < 3; i++) { // loop edges of a single triangle
//
}

//
indicesBuffer[i].put(index++);

incrementColor();
    }



I think this should look like:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
for (each triangle) {
int idx = 0;

for (int i = 0; i < 3; i++) { // loop edges of a single triangle
//
}

//
indicesBuffer[i].put(index++);
indicesBuffer[i].put(index++);
indicesBuffer[i].put(index++);

incrementColor();
    }



As you need 3 indices per triangle (3 vertices, so 3 references to them)




~~

This doesn't explain your shading-problems though, as the above code would only render 1/3 of the model.

I'll check it later, got to go now.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline Wizumwalt

Junior Member




Java games rock!


« Reply #20 - Posted 2006-05-04 17:40:00 »

I'm not clear on what you've got there, I think maybe a typo as your first example of what I've got isn't what I've got. I only increment the colors per triangle, as I understand it, incrementing colors per vertex would change the colors for every vertex position and they all need to be the same color.

Also, when I do a readPixel, the triangle that gets highlighted jumps all over the place as if it were getting 3 random vertices from my model. That part might be too complicated to post so I'll just keep at it, but the colors I don't understand why they're not right.

I try to clarify how my colors are done here. I did change indices as you suggest and now see more colors. Before I thought all the empty triangles were just shades of black I couldn't see and my drawNormally after drawColorCoded fooled me into thinking they were being drawn. I think my next important step is getting the tri's all solid colors.

I do quesiton this line, am I understanding this correctly.
// 3 colors and we store 32 bit ints for each color w/ putInt?
ByteBuffer cBuffer = BufferUtils.newByteBuffer(3 * 4);

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  
for (each triangle) { 
    int idx = 0;

    for (int i = 0; i < 3; i++) { // loop vertices of a single triangle
       // ...
       cBuffer.putInt(idx, getRed());
        triBuffer.put(idx++, (float) node.getX());

        cBuffer.putInt(idx, getGreen());
        triBuffer.put(idx++, (float) node.getY());

        cBuffer.putInt(idx, getBlue());
        triBuffer.put(idx++, (float) node.getZ());

        // by not incrementing colors inside this loop, R, G, and B stay same color.

        indicesBuffer[i].put(index++);
        indicesBuffer[i].put(index++);
        indicesBuffer[i].put(index++);
    }

colorBuffer[i].put(cBuffer); // add 9 colors per 9 vertices of this triangle
elementBuffer[i].put(triBuffer); // add 9 vertices of this triangle to array

incrementColor();
}
Online Riven
« League of Dukes »

JGO Overlord


Medals: 783
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #21 - Posted 2006-05-04 18:21:46 »

first you're specifying the data you upload as GL_UNSIGNED_BYTE

1  
gl.glColorPointer(3, GL.GL_UNSIGNED_BYTE, 0, colorBuffer[index]);


And then you pass an IntBuffer?

You have to encode your index (int) into RGB values (3 bytes, not 3 ints), then read them back as RGB (3 bytes) and decode them into your index.

So put your colors in a ByteBuffer

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline Wizumwalt

Junior Member




Java games rock!


« Reply #22 - Posted 2006-05-04 19:27:48 »

You have to encode your index (int) into RGB values (3 bytes, not 3 ints), then read them back as RGB (3 bytes) and decode them into your index.

So put your colors in a ByteBuffer

I am putting my colors in a ByteBuffer and my colors get incremented with the code below, they're just int value that I put there. I'm sure something here I've not got corrrect and not understanding how to code the RGB values into an index since I already have an index that goes into the indicesBuffer (an IntBuffer). I think I'm thinking that the index into the index buffer pairs up w/ the same index into the color buffer since that color was added the same time that index was add (as in our triangle loops above).

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
   private int red = 0;
   private int green = 0;
   private int blue = 0;
        //...

   public void incrementColor() {
      if (blue < 255) {
         blue++;
      }
      else if (green < 255) {
         green++;
         blue = 0;
      }
      else {
         red++;
         green = 0;
         blue = 0;
      }

      return;
   }


This code is where the RGB gets decoded into an index. Does this index not come out to the same as the index's I'm assigning in the indicesBuffer? Maybe I'm just getting lucky hits.
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
   public void readElementColor(GLAutoDrawable drawable) {
      GL gl = drawable.getGL();
     
      mouseBuffer.clear();
     
      gl.glReadPixels(renderer.getMouseX(), renderer.getMouseY(),
         1, 1, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, mouseBuffer);

      mouseBuffer.rewind();
     
      /*
       *  This turns the byte into an unsigned byte (using the sign-bit as the
       *  ordinary 8th bit of an int, 32bit).
       */

      int r = mouseBuffer.get() & 0xFF;
      int g = mouseBuffer.get() & 0xFF;
      int b = mouseBuffer.get() & 0xFF;

      // Decode the RGB to an index.
     activeTriangleIndex = (r << 16) | (g << 8) | (b << 0);
                 
      return;
   }


How exactly are you coding these colors into an index? I think if I can get past this, then I can assign my indicesBuffer the index from the RGB encoding and not use my method of just incrementing a counter for the index.

Quote from: Riven
triangle 0 [color = 0,0,0]
triangle 1 [color = 0,0,1]
triangle 2 [color = 0,0,2]
triangle 255 [color = 0,0,255]
triangle 256 [color = 0,1,0]
triangle 257 [color = 0,1,1]
triangle 258 [color = 0,1,2]
etc.
Online Riven
« League of Dukes »

JGO Overlord


Medals: 783
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #23 - Posted 2006-05-04 21:42:27 »

You say to OpenGL that the format of your colorbuffer is GL_UNSIGNED_BYTE and has 3 elements (3 bytes)

Now, let's see what yuo are actually sending to the GPU, per elements:

ByteBuffer.putInt(r);
ByteBuffer.putInt(g);
ByteBuffer.putInt(b);

Now count the bytes... an int is 32 bit, a byte is 8 bit. so if you write an int to a buffer, it takes up 4 bytes. So with the above code, you push 12 bytes per element to the GPU, while it expects 3, the result is, well, to be short: it just won't work, because the interpretation of the data is wrong (GPU-side).

With the following code, you will fill your color-buffer with bytes:

ByteBuffer.put((byte)r);
ByteBuffer.put((byte)g);
ByteBuffer.put((byte)b);



HTH

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline Wizumwalt

Junior Member




Java games rock!


« Reply #24 - Posted 2006-05-04 22:17:21 »

Ugh, that worked well and now I have solid colors. I didn't think I could do that because I thought some colors (millions range, not that I would probably get that high) would get truncated by casting like that.

Now to fix the highlighting of the correct triangle. Smiley Thanks for all your help.
Offline Wizumwalt

Junior Member




Java games rock!


« Reply #25 - Posted 2006-05-05 17:52:21 »

Thanks guys, this turned out incredibly nice. I've loaded models w/ several hundred thousand elements and the highlighting actually keeps up w/ the mouse pointer, translation, speedy quick!
Online Riven
« League of Dukes »

JGO Overlord


Medals: 783
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #26 - Posted 2006-05-05 19:02:27 »

 Smiley Great you got it to work!

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline turquoise3232

Junior Member




Java (games) rock!


« Reply #27 - Posted 2006-05-06 09:59:50 »

Yes, that's great! Well done!
Offline DaveLloyd

Junior Member




Making things happen fast with Java!


« Reply #28 - Posted 2006-05-08 10:25:46 »

Quote
Basically you don't use select mode anymore.

Interesting! Would someone enlighten me as to why?

I do use select on scenes with lots of tris and have been wondering about it's performance. Most of my crashes seem to occur in glDrawElements in select mode as well... I would've expected select mode to be efficient as you don't need to do real painting. It's also useful to get the name stack out (Object ID, Subobject ID) and occasionally to see items behind the front tri...

Online Riven
« League of Dukes »

JGO Overlord


Medals: 783
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #29 - Posted 2006-05-08 11:58:51 »

Selction-mode is quite slow by itself (maybe 30% of plain rendering).

The amount of triangles doesn't really matter, it's about the name-count. When doing 1 name per triangle, you're almost back to immediate-mode (as in: gl-call count).

So selection-mode is quite useful, but not a general solution, infact, it's quite limited in use when you care about performance.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Pages: [1] 2
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

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

The first screenshot will be displayed as a thumbnail.

TehJavaDev (17 views)
2014-08-28 18:26:30

CopyableCougar4 (26 views)
2014-08-22 19:31:30

atombrot (39 views)
2014-08-19 09:29:53

Tekkerue (36 views)
2014-08-16 06:45:27

Tekkerue (33 views)
2014-08-16 06:22:17

Tekkerue (22 views)
2014-08-16 06:20:21

Tekkerue (33 views)
2014-08-16 06:12:11

Rayexar (67 views)
2014-08-11 02:49:23

BurntPizza (45 views)
2014-08-09 21:09:32

BurntPizza (36 views)
2014-08-08 02:01:56
List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
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!