Problem with lines disappearing when overriding OnPaint event - TreeView - drawing

I have made my own tree view where I am drawing it myself but something weird happens whenever i scroll or select a node on the tree view
Normal view without selecting or scrolling
View when selecting nodes, line disappear
This is the code:
/// <summary>
/// Override draw event
/// </summary>
protected override void OnPaint(PaintEventArgs e)
{
Graphics Gfx = e.Graphics;
Pen Lines = new Pen(Color.LightSlateGray) { DashPattern = new float[] { 5, 2, 15, 4 } };
foreach (TreeNode n in Nodes)
{
DrawNodes(e, n);
if (n.IsExpanded)
{
foreach (TreeNode n2 in n.Nodes)
{
int X, Y, W, H;
X = n2.Bounds.X;
Y = n2.Bounds.Y;
W = n2.Bounds.Width;
H = n2.Bounds.Height;
// Draw lines
if (n2.Index == 0)
{
Gfx.DrawLine(Lines, new Point(X + AutoScrollOffset.X - 5, Y + AutoScrollOffset.Y + (H / 2)),
new Point(X + AutoScrollOffset.X - 5, Y + AutoScrollOffset.Y + H - 2));
Gfx.DrawLine(Lines, new Point(X + AutoScrollOffset.X - 4, Y + AutoScrollOffset.Y + (H / 2)),
new Point(X + AutoScrollOffset.X - 1, Y + AutoScrollOffset.Y + (H / 2)));
// Draw line to root node
Gfx.DrawLine(Lines, new Point(X + AutoScrollOffset.X - 4, Y + AutoScrollOffset.Y + (H / 2)),
new Point(X + AutoScrollOffset.X - 20, Y + AutoScrollOffset.Y));
}
// End child node
if (n2.Index == SelectedNode.Nodes.Count - 1)
{
Gfx.DrawLine(Lines,
X + AutoScrollOffset.X - 5,
Y + AutoScrollOffset.Y + 2,
X + AutoScrollOffset.X - 5,
Y + AutoScrollOffset.Y + (H / 2));
Gfx.DrawLine(Lines,
X + AutoScrollOffset.X - 4,
Y + AutoScrollOffset.Y + (H / 2),
X + AutoScrollOffset.X - 1,
Y + AutoScrollOffset.Y + (H / 2));
}
// Middle child nodes
if (n2.Index > 0 && n2.Index < SelectedNode.Nodes.Count - 1)
{
Gfx.DrawLine(Lines, new Point(X + AutoScrollOffset.X - 5, Y + AutoScrollOffset.Y + 2),
new Point(X + AutoScrollOffset.X - 5, Y + AutoScrollOffset.Y + H - 2));
Gfx.DrawLine(Lines, new Point(X + AutoScrollOffset.X - 4, Y + AutoScrollOffset.Y + (H / 2)),
new Point(X + AutoScrollOffset.X - 1, Y + AutoScrollOffset.Y + (H / 2)));
}
// Draw the nodes
DrawNodes(e, n2);
}
}
}
}
/// <summary>
/// Draw nodes
/// </summary>
private void DrawNodes(PaintEventArgs e, TreeNode CurNode)
{
// Variables
Font TextFont = new Font("Calibri", 9.0f, FontStyle.Regular);
Font RootFont = new Font("Calibri", 10.0f, FontStyle.Bold);
Image EditIcon = Properties.Resources.Updated;
Color Fore = CurNode.ForeColor;
Color Border = Color.Black;
Color Normal = Color.White;
Color Change = Color.LimeGreen;
Rectangle Bounds = CurNode.Bounds;
Rectangle SBounds = CurNode.Bounds;
Graphics Gfx = e.Graphics;
int X, Y, W, H;
// Separate node bounds
X = Bounds.X + 5;
Y = Bounds.Y;
W = Bounds.Width;
H = Bounds.Height;
// Inflate the bounds so it fits
if (CurNode.Level == 0)
{
// Selection bounds
SBounds.Width = (int)Gfx.MeasureString(CurNode.Text, RootFont).Width - 15;
SBounds.Height = (int)Gfx.MeasureString(CurNode.Text, RootFont).Height - 2;
SBounds.X += 15;
SBounds.Y += 2;
}
else
{
// Selection bounds
SBounds.Width = (int)Gfx.MeasureString(CurNode.Text, TextFont).Width - 5;
SBounds.Height = (int)Gfx.MeasureString(CurNode.Text, TextFont).Height - 2;
SBounds.X += 5;
SBounds.Y += 2;
}
// Set renderer to high quality
Gfx.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
// Draw focus rectangles
if (CurNode == CurNode.TreeView.SelectedNode)
{
// Get current forecolor
Fore = SystemColors.HighlightText;
// Draw blue internal rect
Gfx.FillRectangle(new SolidBrush(Color.LightBlue), SBounds);
// Draw focus rectangle
ControlPaint.DrawFocusRectangle(Gfx, SBounds, Fore, Color.LightBlue);
}
else
// Fill nothing
Gfx.FillRectangle(SystemBrushes.Window, SBounds);
// Child level
if (CurNode.Level > 0)
{
// Get measurement data
MobilityMeasurement MeasureToDisplay = MeasurementManager.GetExistingMeasurement(CurNode.Index);
// Draw text
TextRenderer.DrawText(Gfx, CurNode.Text, TextFont, new Point(X, Y), Color.Black);
// Draw icon for change notification
if (MeasureToDisplay.UpdateMethod == MEAS_UPDATE.UPDATE)
Gfx.DrawImage(EditIcon, new Point(X - 15, Y + 2));
}
// Draw root node text
else
{
// Draw the icons
switch (CurNode.Index)
{
case 0:
// Draw the expand sign
if (CurNode.Nodes.Count > 0 && !CurNode.IsExpanded)
Gfx.DrawImage(Properties.Resources.Expand, new Point(X - 2, Y + (H/2) - (Properties.Resources.Expand.Height/2) + 1));
else if (CurNode.Nodes.Count > 0 && CurNode.IsExpanded)
Gfx.DrawImage(Properties.Resources.DeExpand, new Point(X - 2, Y + (H/2) - (Properties.Resources.Expand.Height/2) + 1));
Gfx.DrawImage(Properties.Resources.ExistingMeas, new Point(X - 20, Y + 2));
break;
case 1:
Gfx.DrawImage(Properties.Resources.NewMeas, new Point(X - 20, Y + 2));
break;
}
// Draw root text
TextRenderer.DrawText(Gfx, CurNode.Text, RootFont, new Point(X + 10, Y + 2), Color.Black);
// Draw lines
//Gfx.DrawLine(new Pen(Color.Red), new Point(X - 5,Y + W), new Point(X - 5,Y + W + 10));
}
}
Does anyone have any suggestions on how i can fix this?
Thank you in advance
-Rowdy

Related

waves from selected pixel (openGL C++)

I've created a program that draws a waving flag and I want to add a functionality that will create new wave on selected pixel, but I can't make it start where I want it to start an that even make the flag stop waving (prob. because of synced sin).
Here's my display func.
const int W = 800;
const int H = 600;
// simulates Frame Buffer
unsigned char pixels[H][W][3] = { 0 }; // 3 is for RGB
void display()
{
glClear(GL_COLOR_BUFFER_BIT); // clean frame buffer
createFlag();
int i, j;
double dist;
offset += 0.25;
for (i = 0; i < H; i++)
for (j = 0; j < W; j++)
{
dist = sqrt(pow(i + H / 2.0, 2) + pow(j + W / 2.0, 2));
pixels[i][j][0] += 135 + 55 * (1 + 1 * sin(dist / 25 - offset)) / 2; // red
pixels[i][j][1] += 135 + 85 * (1 + 1 * sin(dist / 25 - offset)) / 2; // green
pixels[i][j][2] += 135 + 105 * (1 + 1 * sin(dist / 25 - offset)) / 2; // blue
}
// draws the matrix pixels
glDrawPixels(W, H, GL_RGB, GL_UNSIGNED_BYTE, pixels);
glutSwapBuffers(); // show all
}
And here is my mouse func.
void mouse(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
double dist;
offset += 0.1;
for (y = 0; y < H; y++)
for (x = 0; x < W; x++)
{
dist = sqrt(pow(H/2.0 -(H - y), 2) + pow(W/2.0 -x, 2)); //problem is prob. here
pixels[y][x][0] += 135+ 55 * (1 + 1 * sin(dist / 50.0 - offset)) / 2; // red
pixels[y][x][1] += 135+ 85 * (1 + 1 * sin(dist / 50.0 - offset)) / 2; // green
pixels[y][x][2] += 135+105 * (1 + 1 * sin(dist / 50.0 - offset)) / 2; // blue
if (offset < 0.3)
offset += 0.05;
}
}
}
Here are some points that I see:
in your mouse function you don't use your arguments x and y which are the position of your mouse click, instead you create local variables x and y. If you want to start a wave from the pixel you clicked on, you have to center your dist to this point, so an idea of code could be (inspired by GLUT mouse button down):
void mouse(int button, int state, int x, int y)
{
// save the left button state
if (button == GLUT_LEFT_BUTTON)
{
leftMouseButtonDown = (state == GLUT_DOWN);
}
// save the mouse position
mouseXPos = x;
mouseYPos = y;
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT); // clean frame buffer
createFlag();
double dist;
offset += 0.25;
for (i = 0; i < H; i++)
for (j = 0; j < W; j++)
{
dist = sqrt(pow(i + H / 2.0, 2) + pow(j + W / 2.0, 2));
pixels[i][j][0] += 135 + 55 * (1 + 1 * sin(dist / 25 - offset)) / 2; // red
pixels[i][j][1] += 135 + 85 * (1 + 1 * sin(dist / 25 - offset)) / 2; // green
pixels[i][j][2] += 135 + 105 * (1 + 1 * sin(dist / 25 - offset)) / 2; // blue
}
if (leftMouseButtonDown) // the way you can get leftMouseButtonDown depends on your
// configuration of your different files
// (main.cpp, scene.cpp, ...)
new_wave() ; //see below
// draws the matrix pixels
glDrawPixels(W, H, GL_RGB, GL_UNSIGNED_BYTE, pixels);
glutSwapBuffers(); // show all
}
void new_wave()
{
x = mouseXPos ; // same remark as leftMouseButtonDown
y = mouseYPos ;
offset = 0.1;
for (i = 0; i < H; i++) // i and not y
for (j = 0; j < W; j++)
{
dist = sqrt(pow(i - y, 2) + pow(j - x, 2)); // change here
pixels[i][j][0] += 135+ 55 * (1 + 1 * sin(dist / 50.0 - offset)) / 2; // red
pixels[i][j][1] += 135+ 85 * (1 + 1 * sin(dist / 50.0 - offset)) / 2; // green
pixels[i][j][2] += 135+105 * (1 + 1 * sin(dist / 50.0 - offset)) / 2; // blue
if (offset < 0.3)
offset += 0.05;
// I don't really get what you do here with the offset, but another parameter to
// play with could be the amplitude of this wave that starts from the point
// you clicked, like when a drop falls on water
}
}
if you want a real-time waving flag you have to take time as a parameter of your pixels color value
I haven't tested it but I'm not sure on how openGL reacts to RGB coloring with values over 255, which happens in your case, maybe keep that in mind if you still have bugs
dist = sqrt(pow(i + H / 2.0, 2) + pow(j + W / 2.0, 2)); this is centered in (-W/2.0, -H/2.0), is that what you want? (maybe yes just want to make sure, if you want to simulate some wind you could set wind's origin where you want, which is what you do here)
int i, j; in your display isn't useful (just to clear some code)
So these are some remarks I would have made myself, this piece of code probably won't be your final one.
Let me know if I misunderstood what you are aiming to do, or if something I wrote is unclear.

How to have text centered inside each slice of a pie chart?

I would like to get the text labels (percentages) centered within each pie slice. It currently works a bit for two of the quadrants:
What am I doing wrong?
void PieChartWidget::paintEvent(QPaintEvent *) {
QPainter painter(this);
QRectF size;
painter.setPen(QPen(Qt::black, 2));
if (this->height() > this->width()) {
size = QRectF(5, 5, this->width() - 10, this->width() - 10);
} else {
size = QRectF(5, 5, this->height() - 5, this->height() - 10);
}
double sum = 0.0, startAng = 0.0;
double angle, endAng;
double percent;
for (int i = 0; i < qvValues.size(); i++) {
sum += qvValues[i];
}
for (int i = 0; i < qvValues.size(); i++) {
percent = qvValues[i] / sum;
angle = percent * 360.0;
endAng = startAng + angle;
painter.setBrush(qvColors[i]);
painter.drawPie(size, static_cast<int>(startAng * 16),
static_cast<int>(angle * 16));
startAng = endAng;
if (percent != 0) {
double draw_x = width() / 2 +
cos(PI * (endAng / 180.0 - angle / 360.0)) * this->width() / 4.0;
double draw_y = height() / 2 +
sin(PI * (endAng / 180.0 - angle / 360.0)) * this->width() / 4.0;
painter.drawText(draw_x, draw_y, QString::number(percent * 100) + "%");
}
}
}
On this line:
painter.drawText(this->width()/4,this->height(), QString::number(percent*100)+"%");
You seem to draw the percentage in the same place every time. You do successfully draw the percentage for each section, they're just being drawn in the same place every time. Try changing it to this:
painter.drawText(double(i + 1) * this->width()/4,this->height(), QString::number(percent*100)+"%");
And you'll see what I mean. By multiplying the x value by some changing value, the x position of each drawn text will change, and thus you will be able to see the different percentages being drawn.
If you want it to draw in each quadrant, then your code might look something like this:
# define PI 3.14159265358979323846
...
double draw_x = this->width / 2.0 + cos(PI * (end_angle / 180.0 - angle / 360.0)) * this->width / 4.0;
double draw_y = this->height / 2.0 - sin(PI * (end_angle / 180.0 - angle / 360.0)) * this->width / 4.0;
painter.drawText(draw_x, draw_y, QString::number(percent*100)+"%");
Basically, what's happening in the above code is I'm calculating the x and y coords of the middle of each slice. Then, I'm drawing the percentages in those positions.

Manipulating sfml Vertex Array

I am doing research on the sfml Vertex Array functions.Based on this tutorial I've been introduced to a basic implementation and am wanting to add to it. Unfortunately I am relatively new at OOP and would appreciate any help adding to this.
The output generates a checkerboard like pattern using a sprite grid.
My goal is to connect the grid-floor tiles using a pathfinding algorithm(recursive bactracker) to generate a path.
the rest of this part is instantiated in the main.cpp:
//load the texture for our background vertex array
Texture textureBackground;
textureBackground.loadFromFile("graphics/background_sheet.png");
once in the game loop as:
//pass the vertex array by reference to the createBackground function
int tileSize = createBackground(background, arena);
and finally in the draw scene:
window.draw(background, &textureBackground);
#include "stdafx.h"
#include <SFML/Graphics.hpp>
#include "zArena.h"
int createBackground(VertexArray& rVA, IntRect arena)
{
// Anything we do to rVA we are actually doing to background (in the main function)
// How big is each tile/texture
const int TILE_SIZE = 50;
const int TILE_TYPES = 3;
const int VERTS_IN_QUAD = 4;
int worldWidth = arena.width / TILE_SIZE;
int worldHeight = arena.height / TILE_SIZE;
// What type of primitive are we using?
rVA.setPrimitiveType(Quads);
// Set the size of the vertex array
rVA.resize(worldWidth * worldHeight * VERTS_IN_QUAD);
// Start at the beginning of the vertex array
int currentVertex = 0;
for (int w = 0; w < worldWidth; w++)
{
for (int h = 0; h < worldHeight; h++)
{
// Position each vertex in the current quad
rVA[currentVertex + 0].position = Vector2f(w * TILE_SIZE, h * TILE_SIZE);
rVA[currentVertex + 1].position = Vector2f((w * TILE_SIZE) + TILE_SIZE, h * TILE_SIZE);
rVA[currentVertex + 2].position = Vector2f((w * TILE_SIZE) + TILE_SIZE, (h * TILE_SIZE) + TILE_SIZE);
rVA[currentVertex + 3].position = Vector2f((w * TILE_SIZE), (h * TILE_SIZE) + TILE_SIZE);
// Define the position in the Texture to draw for current quad
// Either mud, stone, grass or wall
//if (h == 0 || h == worldHeight - 1 || w == 0 || w == worldWidth - 1)
if ((h % 2 !=0)&& (w % 2 != 0))
{
// Use the wall texture
rVA[currentVertex + 0].texCoords = Vector2f(0, 0 + TILE_TYPES * TILE_SIZE);
rVA[currentVertex + 1].texCoords = Vector2f(TILE_SIZE, 0 + TILE_TYPES * TILE_SIZE);
rVA[currentVertex + 2].texCoords = Vector2f(TILE_SIZE, TILE_SIZE + TILE_TYPES * TILE_SIZE);
rVA[currentVertex + 3].texCoords = Vector2f(0, TILE_SIZE + TILE_TYPES * TILE_SIZE);
}
else
{
// Use a random floor texture
srand((int)time(0) + h * w - h);
int mOrG = (rand() % TILE_TYPES);
int verticalOffset = mOrG * TILE_SIZE;
//int verticalOffset = 0;
rVA[currentVertex + 0].texCoords = Vector2f(0, 0 + verticalOffset);
rVA[currentVertex + 1].texCoords = Vector2f(TILE_SIZE, 0 + verticalOffset);
rVA[currentVertex + 2].texCoords = Vector2f(TILE_SIZE, TILE_SIZE + verticalOffset);
rVA[currentVertex + 3].texCoords = Vector2f(0, TILE_SIZE + verticalOffset);
}
// Position ready for the next for vertices
currentVertex = currentVertex + VERTS_IN_QUAD;
}
}
return TILE_SIZE;
}
As far as i see, there you're generating your tiles on the fly. If you want to create something like a walkable space, you should generate your tile map first, and then draw it based on the content generated.
Maybe overkilling your question, there are several ways to generate random maps satisfying specific constraints.
When you have the choice done, then you can simply draw as you do, but instead of
// Use a random floor texture
srand((int)time(0) + h * w - h);
int mOrG = (rand() % TILE_TYPES);
int verticalOffset = mOrG * TILE_SIZE;
should have something like
// Select texture rect based on generated tilemap
int mOrG = tilemap[w][h]; // Or tilemap[h * worldWidth + w] if you do it as unidimensional array
int verticalOffset = mOrG * TILE_SIZE;
With this approach you must pass tilemap to your render method or, even better, create a TileMap class overriding draw() method

Shrinking images using recursion incorrect positioning

I am writing code that takes an image and creates subimages within the original image. I am doing this recursively with a rectangle class that keeps track of starting and stopping positions of the subimage. After the 3rd recursive call is where i run into trouble. The new subimages are being placed in the incorrect spots. They should be shrinking as they approach the top right corner of the image. I have run through the debugger and watched the start and stop positions change with each call and they reflect movement toward the top right corner. The only place I think the error could be is where I create a new rectangle called rRight to be put into the recursive call.
int main()
{
CImage original("test256.gif");
Rectangle rPrev(0, 0, original.getRows(), original.getCols());
Rectangle r(0, 0, (original.getRows() / 2), (original.getCols() / 2));
CImage final = fractal(original, r, rPrev);
final.output("output.gif");
system("PAUSE");
return 0;
}
CImage fractal(CImage &origin, Rectangle &r, Rectangle &rPrev)
{
if (r.getX2() - r.getX1() > 0 && r.getY2() - r.getY1() > 0)
{
drawTopLeft(origin, r, rPrev);
Rectangle rRight(0, r.getY2(), (r.getX2() / 2), (r.getY2() + ((r.getY2() - r.getY1()) / 2)));
fractal(origin, rRight, r);
}
return origin;
}
void drawTopLeft(CImage &origin, Rectangle &r, Rectangle &rPrev)
{
for (int row = rPrev.getX1(); row < rPrev.getX2(); row += 2)
{
for (int col = rPrev.getY1(); col < rPrev.getY2(); col += 2)
{
pixel p1 = origin.getPixel(row, col);
pixel p2 = origin.getPixel(row + 1, col);
pixel p3 = origin.getPixel(row, col + 1);
pixel p4 = origin.getPixel(row + 1, col + 1);
int avgRed = (p1.red + p2.red + p3.red + p4.red) / 4;
int avgGreen = (p1.green + p2.green + p3.green + p4.green) / 4;
int avgBlue = (p1.blue + p2.blue + p3.blue + p4.blue) / 4;
origin.setPixel((row / 2) + r.getX1(), (col / 2) + r.getY1(), avgRed, avgGreen, avgBlue);
}
}
}

glReadPixels moving coordinates with zoom

I'm trying to read a rectangle of pixels by selecting two points (opposite corners) using glReadPixels with C++ code. The problem comes out when selecting the Y-Axis value.
At the moment, I manage to get the glReadPixels work until zooming. When you zoom (in or out), the tool reads pixels from other Y values (the X are always OK)
What am I doing wrong?
GLORTHO:
IZDA = mCameraPosition.x - ((double)(rectangleDim.x/SCRARatio)) * mZoomFactor / 2;
DCHA = mCameraPosition.x + ((double)(rectangleDim.x/SCRARatio)) * mZoomFactor / 2
ABAJO = mCameraPosition.y - ((double)rectangleDim.y) * mZoomFactor / 2;
ARRIBA = mCameraPosition.y + ((double)rectangleDim.y) * mZoomFactor / 2;
glOrtho(IZDA, DCHA, ABAJO, ARRIBA, -1.0f, 1.0f);
GETSCREENCOORDS
realDim.x = dimension.x * (dimension.x * mZoomFactor / 2);
realDim.y = dimension.y * (dimension.y * mZoomFactor / 2);
GSC.x = (dimension.x*(x-mCameraPosition.x)) / realDim.x;
GSC.y = (dimension.y/realDim.y) * ((pow(dimension.y, 2)*mZoomFactor/2)+mCameraPosition.y + y - imgDim.y);
GETWORLDCOORDS
realDim.x = dimension.x * (dimension.x * mZoomFactor / 2);
realDim.y = dimension.y * (dimension.y * mZoomFactor / 2);
GWC.x =
((x * realDim.x) / dimension.x) + mCameraPosition.x;
GWC.y =
((y * realDim.y) / dimension.y)
-((dimension.y * (dimension.y * mZoomFactor/2)) + mCameraPosition.y)
+ imgDim.y;
CHECKFILLVALUE (Using glReadPixels)
ComplexData::Point a, b;
// Set points screen coordinates
getScreenCoords(FIP.x, FIP.y);
a.x = GSC.x;
a.y = GSC.y;
getScreenCoords(FEP.x, FEP.y);
b.x = GSC.x;
b.y = GSC.y;
// Set length and width to read (and write)
double RX_Length, RY_Length;
if (b.x < a.x) RX_Length = a.x - b.x;
else RX_Length = b.x - a.x;
if (b.y < a.y) RY_Length = a.y - b.y;
else RY_Length = b.y - a.y;
// Pixel data vector
float *tdata = new float[3*RX_Length*RY_Length];
double desp = (mZoomFactor*dvcamera)/dvzoom;
getScreenCoords(min(FIP.x, FEP.x), gHeight-FIP.y-2*(mCameraPosition.y-desp));
// Reading from the GET SCREEN COORDINATES global values (GSC)
glReadPixels(GSC.x, GSC.y, RX_Length, RY_Length, GL_RGB, GL_FLOAT, tdata); // <--- Works great until zooming
glRasterPos2d(min(FIP.x, FEP.x), gHeight-max(FIP.y, FEP.y));
glDrawPixels(RX_Length, RY_Length, GL_RGB, GL_FLOAT, tdata); // <--- Works great
delete[] tdata;
MOUSEWHEEL (Zoom)
Drawing::Point pt = e->Location;
getWorldCoords(pt.X, pt.Y);
Initial_Zoom.X = rectangleDim.x - GWC.x;
Initial_Zoom.Y = GWC.y;
// ZOOM IN
if (e->Delta > 0){
if (mZoomFactor > float::Epsilon * 1000.0f){
mZoomFactor /= 1.15f;
}
}
// ZOOM OUT
else {
if (mZoomFactor < float::MaxValue / 1000.0f){
mZoomFactor *= 1.15f;
}
}
I manage to find the solution.
Replace:
getScreenCoords(min(FIP.x, FEP.x), gHeight-FIP.y-2*(mCameraPosition.y-desp));
glReadPixels(GSC.x, GSC.y, RX_Length, RY_Length, GL_RGB, GL_FLOAT, tdata);
With:
getScreenCoords(std::min(FIP.x, FEP.x), FIP.y);
glReadPixels(GSC.x, rectangleDim.y - GSC.y, RX, RY, GL_RGB, GL_FLOAT, tdata);
And voilá. It works ^^