-
Notifications
You must be signed in to change notification settings - Fork 4
Tutorial: Drawing a texture
To begin, create a new windows form application and add the following variables to the top:
renderX GL;
GLBuffer vertexBuffer;
Shader cubeShader;
Vector3 cameraPosition, cameraRotation;
Next lets declare both our shaders:
unsafe void CubeVS(float* OUT, float* IN, int Index){
OUT[0] = IN[0] * 50;
OUT[1] = IN[1] * 50;
OUT[2] = IN[2] * 50;
}
unsafe void CubeFS(byte* BGR, float* Attributes, int Index){
float u = Attributes[0] * 255f;
float v = Attributes[1] * 255f;
BGR[0] = (byte)u;
BGR[1] = (byte)v;
}
After that lets create our renderFrame method:
void timer_Tick(object sender, EventArgs e)
{
GL.Clear(0, 0, 0);
GL.ClearDepth();
GL.SelectBuffer(vertexBuffer);
GL.SelectShader(cubeShader);
GL.Draw();
GL.Blit();
}
Note: I recommend you use the RenderThread included, however this short demo will do fine with a 15.6ms limited timer
Lastly, lets add the Form1_Load
event and add the following code:
//Set the form size to 800x600
this.ClientSize = new System.Drawing.Size(800, 600);
//Initialize the renderer
GL = new renderX(800, 600, this.Handle);
//Create a buffer from our included cube with uv map primitive
vertexBuffer = new GLBuffer(renderX.PrimitiveTypes.Cube(), 5, MemoryLocation.Heap);
//Initialize the shader
cubeShader = new Shader(CubeVS, CubeFS, GLRenderMode.Triangle);
cameraPosition = new Vector3(0, 0, -100);
cameraRotation = new Vector3(0, 0, 0);
GL.SetMatrixData(90, 160, 0);
GL.ForceCameraPosition(cameraPosition);
GL.ForceCameraRotation(cameraRotation);
GL.SetFaceCulling(true, false);
//create and initialize a timer
Timer timer = new Timer();
timer.Interval = 15;
timer.Tick += timer_Tick;
timer.Start();
Once you run the code you should see this:
However, that is just our UV coordinates, so lets add a texture.
To start, add the following lines:
public float Clamp01(float value){
if (value < 0) return 0f;
else if (value > 1) return 1f;
else return value;
}
Next, lets add our texture references at the top:
GLTexture texture2d;
int* TEXTURE_ADDR;
int textureWidthMinusOne, textureHeightMinusOne, textureHeight;
Next up, in the Form load method add these lines to initialize and load a texture:
texture2d = new GLTexture("myTexture.png", MemoryLocation.Heap, DuringLoad.Flip);
TEXTURE_ADDR = (int*)texture2d.GetAddress();
textureHeight = texture2d.Height;
textureWidthMinusOne = texture2d.Width - 1;
textureHeightMinusOne = texture2d.Height - 1;
Lastly, modify your fragment shader to look like this:
unsafe void CubeFS(byte* BGR, float* Attributes, int Index){
int U = (int)(Clamp01(Attributes[0]) * textureWidthMinusOne);
int V = (int)(Clamp01(Attributes[1]) * textureHeightMinusOne);
*((int*)BGR) = TEXTURE_ADDR[U + V * textureHeight];
}
It is important to clamp your texture, because otherwise your application will crash if you read out side of the buffer.
If everything is done correctly, your form should look like this:
- Initializing the renderer
- Setting the transform data
- Blitting and clearing the viewport
- Initializing a vertex buffer
- Creating a shader
- Drawing an object
- Screen space shaders
- Blitting bitmaps
- Loading a texture
- Creating a framebuffer
- Displaying a texture