Author Topic: Manually Drawing non-tiled Graphics (3D for example)  (Read 1260 times)

bluemonkmn

  • SGDK Author
  • Administrator
  • Fanatic
  • *****
  • Posts: 2752
    • ICQ Messenger - 2678251
    • MSN Messenger - BlueMonkMN@gmail.com
    • View Profile
    • http://sgdk2.sf.net/
    • Email
Manually Drawing non-tiled Graphics (3D for example)
« on: 2012-03-04, 07:59:04 AM »
This is in response to a question asked by #Sharp about drawing a sky box with textures applied. Apparently the part about drawing the box is already worked out by doing the drawing right before DrawAllViews in GameForm.cs.  The next question is about applying a texture to it.  OpenGL textures are most closely associated with SGDK2 graphic sheets.  But much of that code is generated by SGDK2 and not visible in the source code folder.  So if you want to look at example code, you have to look at a generated project's "Frameset.cs" file instead of in the source code folder of the project in the IDE.  The key function to notice is Display.GetTextureRef, which you will see called many times in Frameset.cs.  Basically, it looks up a graphic sheet by name and returns the existing (or newly created, if it's the first call) reference to the texture as an instance of Display.TextureRef.  Now you have enough information that you can refer to Display.cs to see how the rest works.  You can see that GetTextureRef just refers to an internal map of names to TextureRef objects maintained in the Display class.  And you can see that TextureRef has a property Texture that returns the OpenGL texture handle (an integer).  If you are interacting with OpenTK/OpenGL directly, that handle is what you'd use.  If you are using the DrawFrame function of the Display (or adding your own function to Display), you can pass the TextureRef object directly.  But at the OpenGL, level, you would call GL.BindTexture, passing the Texture property of the TextureRef instance to set the current texture to the desired graphic sheet image.

v6v

  • Clever
  • Fanatic
  • ***
  • Posts: 500
  • Has renamed his project to Galaxy!
    • View Profile
    • My Developer Page!
    • Email
Re: Manually Drawing non-tiled Graphics (3D for example)
« Reply #1 on: 2012-03-04, 11:15:50 AM »
Ah,I see.

GetTextureRef returns a TextureRef object so
Inside Display.cs:

string bluesky = "bluesky"; //A 64 x 64 1 by 1 Graphic sheet.
TextureRef BlueSky = GetTextureRef(bluesky);
GL.BindTexture(TextureTarget.Texture2D, BlueSky.Texture); //Assuming I'm using 2D Textures because I have absolutely no idea what a 3D Texture is
//The Skybox is a set of Quads drawn within the Depth buffer in 3D Space as a cube, it may not be entirely efficient.

//Draw my Quads..?

http://www.khronos.org/opengles/documentation/opengles1_0/html/glBindTexture.html

Pseudocode seems legit. I'll post my results in shortly.
I'm going to try this against the whole power of two issue, but the texture sizes are arbitrary, right?

Edit 1: 52 x 52 graphic after following the rule posted here:
2*(25) + 2
http://www.opengl.org/sdk/docs/man/xhtml/glTexImage2D.xml
However, I am getting an eexception that after rounding up to 64 x 64 by a power of two, and the exception says that my computer only supports graphics up to size 0
(I'm not entirely sure the logic to this, but I'm looking toward the requirements for texture sizes.)

Edit 2:
Resized to 128x128, because of the 64 by 64 minimum. Still, the same exception is thrown.

Edit 3:
This one is somewhat embarrassing. I hastily slapped the pseudocode into my DrawSkyBox() funciton in Display.cs. It turns out that the function was wedged between GL.Begin and GL.End, and it's best to not perform these actions between GL.Begin and GL.End, something learned from my shader attempt.

Edit 4:
I can't seem to find documentation for GL.TexCoord3, but I can get the first texel/pixel in the texture, however, it seems to only draw the first texel as the entire texture, leaving my cube as one solid color.

Code: [Select]
     GL.Begin(BeginMode.Quads);
            //GL.Color3(System.Drawing.Color.Silver);
            GL.TexCoord3(1, 1, 0);
            GL.Vertex3(-1.0f, -1.0f, -1.0f);
            GL.Vertex3(-1.0f, 1.0f, -1.0f);
            GL.Vertex3(1.0f, 1.0f, -1.0f);
            GL.Vertex3(1.0f, -1.0f, -1.0f);
 
            //GL.Color3(System.Drawing.Color.Honeydew);
            GL.TexCoord3(1, 1, 0);
            GL.Vertex3(-1.0f, -1.0f, -1.0f);
            GL.Vertex3(1.0f, -1.0f, -1.0f);
            GL.Vertex3(1.0f, -1.0f, 1.0f);
            GL.Vertex3(-1.0f, -1.0f, 1.0f);
 
            //GL.Color3(System.Drawing.Color.Moccasin);
            GL.TexCoord3(1, 1, 0);
            GL.Vertex3(-1.0f, -1.0f, -1.0f);
            GL.Vertex3(-1.0f, -1.0f, 1.0f);
            GL.Vertex3(-1.0f, 1.0f, 1.0f);
            GL.Vertex3(-1.0f, 1.0f, -1.0f);
 
            //GL.Color3(System.Drawing.Color.IndianRed);
            GL.TexCoord3(1, 1, 0);      
            GL.Vertex3(-1.0f, -1.0f, 1.0f);
            GL.Vertex3(1.0f, -1.0f, 1.0f);
            GL.Vertex3(1.0f, 1.0f, 1.0f);
            GL.Vertex3(-1.0f, 1.0f, 1.0f);
 
            //GL.Color3(System.Drawing.Color.PaleVioletRed);
            GL.TexCoord3(1, 1, 0);
            GL.Vertex3(-1.0f, 1.0f, -1.0f);
            GL.Vertex3(-1.0f, 1.0f, 1.0f);
            GL.Vertex3(1.0f, 1.0f, 1.0f);
            GL.Vertex3(1.0f, 1.0f, -1.0f);
 
            //GL.Color3(System.Drawing.Color.ForestGreen);
            GL.TexCoord3(1, 1, 0);
            GL.Vertex3(1.0f, -1.0f, -1.0f);
            GL.Vertex3(1.0f, 1.0f, -1.0f);
            GL.Vertex3(1.0f, 1.0f, 1.0f);
            GL.Vertex3(1.0f, -1.0f, 1.0f);
 
            GL.End();

}
This code doesn't allow me to use the entire texture, but however, it only uses the first texel/pixel in the texture for texturing, making the shape a solid color.

Final Edit:
Ok, mapped the texture to the Quad coordinates, never worked with Textures in 3D, it seemed that it was using the last pixel. I've managed to get the texture stuck to the skybox now.
My final question is, any transparency in the PNG, is it automatically handled when I map the texture?


It may be hard to make out what's going on here, but the first image shows the texture mapped with DrawAllViews disabled, and the second shows it during execution of DrawAllViews enabled.
Only think left to do is to map the textures to "INSIDE" of the cube, but I think I can handle that.

Conclusion Edit
Using GL.Rotate I've achieved the Skybox I was hoping for. The Game is contained within a 3D box with a sky texture mapped to it. I will upload a video soon. This is EXACTLY what I was looking for! I never expected to accomplish it before College! In any case, a class called SkyBox.cs controls what Sky is being drawn, so daytime, nighttime, stormy,etc.

Next- create a smaller box with a transparent cloud texture. I need to create a smaller box, and add the cloud texture to it, then rotate it in the opposite direction than the sky.
« Last Edit: 2012-03-08, 04:06:53 PM by #Sharp »

v6v

  • Clever
  • Fanatic
  • ***
  • Posts: 500
  • Has renamed his project to Galaxy!
    • View Profile
    • My Developer Page!
    • Email

v6v

  • Clever
  • Fanatic
  • ***
  • Posts: 500
  • Has renamed his project to Galaxy!
    • View Profile
    • My Developer Page!
    • Email
Re: Manually Drawing non-tiled Graphics (3D for example)
« Reply #3 on: 2012-03-08, 04:08:51 PM »
If anyone's still following this thread, the SkyBox object has been updated to support both Domes and Boxes. The object can draw either primitive, and accepts a graphic sheet as it's parameter. The player movement is synced X Y and Z rotation to the sky.

Hopefully when I'm satisfied enough with it for public viewing, I'll release it with a demo. :)