Merge pull request #1262 from vpelletier/tinygl_dirty2d

GRIM: Fix drawLine/Rect/Polygon in TinyGL renderer
This commit is contained in:
Paweł Kołodziejski 2016-07-18 05:17:35 +02:00 committed by GitHub
commit d467980499
6 changed files with 111 additions and 100 deletions

View file

@ -1953,33 +1953,12 @@ void GfxOpenGL::drawRectangle(const PrimitiveObject *primitive) {
glVertex2f(x1, y2 + 1);
glEnd();
} else {
glBegin(GL_QUADS);
// top line
glLineWidth(_scaleW);
glBegin(GL_LINE_LOOP);
glVertex2f(x1, y1);
glVertex2f(x2 + 1, y1);
glVertex2f(x2 + 1, y1 + 1);
glVertex2f(x1, y1 + 1);
// right line
glVertex2f(x2, y1);
glVertex2f(x2 + 1, y1);
glVertex2f(x2 + 1, y2 + 1);
glVertex2f(x2, y2);
// bottom line
glVertex2f(x1, y2);
glVertex2f(x2 + 1, y2);
glVertex2f(x2 + 1, y2 + 1);
glVertex2f(x1, y2 + 1);
// left line
glVertex2f(x1, y1);
glVertex2f(x1 + 1, y1);
glVertex2f(x1 + 1, y2 + 1);
glVertex2f(x1, y2);
glEnd();
}

View file

@ -1368,62 +1368,79 @@ void GfxTinyGL::irisAroundRegion(int x1, int y1, int x2, int y2) {
}
void GfxTinyGL::drawRectangle(const PrimitiveObject *primitive) {
int x1 = primitive->getP1().x;
int y1 = primitive->getP1().y;
int x2 = primitive->getP2().x;
int y2 = primitive->getP2().y;
float x1 = primitive->getP1().x * _scaleW;
float y1 = primitive->getP1().y * _scaleH;
float x2 = primitive->getP2().x * _scaleW;
float y2 = primitive->getP2().y * _scaleH;
const Color color(primitive->getColor());
const Color &color = primitive->getColor();
uint32 c = _pixelFormat.RGBToColor(color.getRed(), color.getGreen(), color.getBlue());
tglMatrixMode(TGL_PROJECTION);
tglLoadIdentity();
tglOrtho(0, _screenWidth, _screenHeight, 0, 0, 1);
tglMatrixMode(TGL_MODELVIEW);
tglLoadIdentity();
tglDisable(TGL_LIGHTING);
tglDisable(TGL_DEPTH_TEST);
tglDepthMask(TGL_FALSE);
tglColor3ub(color.getRed(), color.getGreen(), color.getBlue());
if (primitive->isFilled()) {
for (; y1 <= y2; y1++)
if (y1 >= 0 && y1 < _gameHeight)
for (int x = x1; x <= x2; x++)
if (x >= 0 && x < _gameWidth)
_zb->writePixel(_gameWidth * y1 + x, c);
tglBegin(TGL_QUADS);
tglVertex2f(x1, y1);
tglVertex2f(x2 + 1, y1);
tglVertex2f(x2 + 1, y2 + 1);
tglVertex2f(x1, y2 + 1);
tglEnd();
} else {
if (y1 >= 0 && y1 < _gameHeight)
for (int x = x1; x <= x2; x++)
if (x >= 0 && x < _gameWidth)
_zb->writePixel(_gameWidth * y1 + x, c);
if (y2 >= 0 && y2 < _gameHeight)
for (int x = x1; x <= x2; x++)
if (x >= 0 && x < _gameWidth)
_zb->writePixel(_gameWidth * y2 + x, c);
if (x1 >= 0 && x1 < _gameWidth)
for (int y = y1; y <= y2; y++)
if (y >= 0 && y < _gameHeight)
_zb->writePixel(_gameWidth * y + x1, c);
if (x2 >= 0 && x2 < _gameWidth)
for (int y = y1; y <= y2; y++)
if (y >= 0 && y < _gameHeight)
_zb->writePixel(_gameWidth * y + x2, c);
tglBegin(TGL_LINE_LOOP);
tglVertex2f(x1, y1);
tglVertex2f(x2 + 1, y1);
tglVertex2f(x2 + 1, y2 + 1);
tglVertex2f(x1, y2 + 1);
tglEnd();
}
tglColor3f(1.0f, 1.0f, 1.0f);
tglDepthMask(TGL_TRUE);
tglEnable(TGL_DEPTH_TEST);
tglEnable(TGL_LIGHTING);
}
void GfxTinyGL::drawLine(const PrimitiveObject *primitive) {
int x1 = primitive->getP1().x;
int y1 = primitive->getP1().y;
int x2 = primitive->getP2().x;
int y2 = primitive->getP2().y;
float x1 = primitive->getP1().x * _scaleW;
float y1 = primitive->getP1().y * _scaleH;
float x2 = primitive->getP2().x * _scaleW;
float y2 = primitive->getP2().y * _scaleH;
const Color &color = primitive->getColor();
if (x2 == x1) {
for (int y = y1; y <= y2; y++) {
if (x1 >= 0 && x1 < _gameWidth && y >= 0 && y < _gameHeight)
_zb->writePixel(_gameWidth * y + x1, color.getRed(), color.getGreen(), color.getBlue());
}
} else {
float m = (y2 - y1) / (float)(x2 - x1);
int b = (int)(-m * x1 + y1);
for (int x = x1; x <= x2; x++) {
int y = (int)(m * x) + b;
if (x >= 0 && x < _gameWidth && y >= 0 && y < _gameHeight)
_zb->writePixel(_gameWidth * y + x, color.getRed(), color.getGreen(), color.getBlue());
}
}
tglMatrixMode(TGL_PROJECTION);
tglLoadIdentity();
tglOrtho(0, _screenWidth, _screenHeight, 0, 0, 1);
tglMatrixMode(TGL_MODELVIEW);
tglLoadIdentity();
tglDisable(TGL_LIGHTING);
tglDisable(TGL_DEPTH_TEST);
tglDepthMask(TGL_FALSE);
tglColor3ub(color.getRed(), color.getGreen(), color.getBlue());
// tglLineWidth(_scaleW); // Not implemented in TinyGL
tglBegin(TGL_LINES);
tglVertex2f(x1, y1);
tglVertex2f(x2, y2);
tglEnd();
tglColor3f(1.0f, 1.0f, 1.0f);
tglDepthMask(TGL_TRUE);
tglEnable(TGL_DEPTH_TEST);
tglEnable(TGL_LIGHTING);
}
void GfxTinyGL::drawDimPlane() {
@ -1460,34 +1477,44 @@ void GfxTinyGL::drawDimPlane() {
}
void GfxTinyGL::drawPolygon(const PrimitiveObject *primitive) {
int x1 = primitive->getP1().x;
int y1 = primitive->getP1().y;
int x2 = primitive->getP2().x;
int y2 = primitive->getP2().y;
int x3 = primitive->getP3().x;
int y3 = primitive->getP3().y;
int x4 = primitive->getP4().x;
int y4 = primitive->getP4().y;
float m;
int b;
float x1 = primitive->getP1().x * _scaleW;
float y1 = primitive->getP1().y * _scaleH;
float x2 = primitive->getP2().x * _scaleW;
float y2 = primitive->getP2().y * _scaleH;
float x3 = primitive->getP3().x * _scaleW;
float y3 = primitive->getP3().y * _scaleH;
float x4 = primitive->getP4().x * _scaleW;
float y4 = primitive->getP4().y * _scaleH;
const Color &color = primitive->getColor();
uint32 c = _pixelFormat.RGBToColor(color.getRed(), color.getGreen(), color.getBlue());
m = (y2 - y1) / (x2 - x1);
b = (int)(-m * x1 + y1);
for (int x = x1; x <= x2; x++) {
int y = (int)(m * x) + b;
if (x >= 0 && x < _gameWidth && y >= 0 && y < _gameHeight)
_zb->writePixel(_gameWidth * y + x, c);
}
m = (y4 - y3) / (x4 - x3);
b = (int)(-m * x3 + y3);
for (int x = x3; x <= x4; x++) {
int y = (int)(m * x) + b;
if (x >= 0 && x < _gameWidth && y >= 0 && y < _gameHeight)
_zb->writePixel(_gameWidth * y + x, c);
}
tglMatrixMode(TGL_PROJECTION);
tglLoadIdentity();
tglOrtho(0, _screenWidth, _screenHeight, 0, 0, 1);
tglMatrixMode(TGL_MODELVIEW);
tglLoadIdentity();
tglDisable(TGL_LIGHTING);
tglDisable(TGL_DEPTH_TEST);
tglDepthMask(TGL_FALSE);
tglColor3ub(color.getRed(), color.getGreen(), color.getBlue());
tglBegin(TGL_LINES);
tglVertex2f(x1, y1);
tglVertex2f(x2 + 1, y2 + 1);
tglEnd();
tglBegin(TGL_LINES);
tglVertex2f(x3, y3 + 1);
tglVertex2f(x4 + 1, y4);
tglEnd();
tglColor3f(1.0f, 1.0f, 1.0f);
tglDepthMask(TGL_TRUE);
tglEnable(TGL_DEPTH_TEST);
tglEnable(TGL_LIGHTING);
}
void GfxTinyGL::readPixels(int x, int y, int width, int height, uint8 *buffer) {

View file

@ -113,6 +113,10 @@ void tglColor3fv(float *v) {
tglColor4f(v[0], v[1], v[2], 1);
}
void tglColor3ub(unsigned char r, unsigned char g, unsigned char b) {
tglColor4f(r / 255.0f, g / 255.0f, b / 255.0f, 1.0f);
}
void tglColor4ub(unsigned char r, unsigned char g, unsigned char b, unsigned char a) {
tglColor4f(r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f);
}

View file

@ -744,6 +744,7 @@ PROTO_GL4(Vertex)
PROTO_GL3(Color)
PROTO_GL4(Color)
void tglColor3ub(unsigned char r, unsigned char g, unsigned char b);
void tglColor4ub(unsigned char r, unsigned char g, unsigned char b,
unsigned char a);

View file

@ -238,10 +238,10 @@ void glopOrtho(GLContext *context, GLParam *p) {
float tz = -(zFar + zNear) / (zFar - zNear);
r = &m._m[0][0];
r[0] = a; r[1] = 0; r[2] = 0; r[3] = 0;
r[4] = 0; r[5] = b; r[6] = 0; r[7] = 0;
r[8] = 0; r[9] = 0; r[10] = c; r[11] = 0;
r[12] = tx; r[13] = ty; r[14] = tz; r[15] = 0;
r[0] = a; r[1] = 0; r[2] = 0; r[3] = tx;
r[4] = 0; r[5] = b; r[6] = 0; r[7] = ty;
r[8] = 0; r[9] = 0; r[10] = c; r[11] = tz;
r[12] = 0; r[13] = 0; r[14] = 0; r[15] = 1;
*context->matrix_stack_ptr[context->matrix_mode] *= m;
gl_matrix_update(context);

View file

@ -393,10 +393,10 @@ void RasterizationDrawCall::execute(bool restoreState) const {
break;
case TGL_LINE_STRIP:
case TGL_LINE_LOOP:
for(int i = 0; i < cnt; i++) {
for(int i = 0; i < cnt - 1; i++) {
gl_draw_line(c, &c->vertex[i], &c->vertex[i + 1]);
}
gl_draw_line(c, &c->vertex[0], &c->vertex[cnt - 1]);
gl_draw_line(c, &c->vertex[cnt - 1], &c->vertex[0]);
break;
case TGL_TRIANGLES:
for(int i = 0; i < cnt / 3; i++) {
@ -424,7 +424,7 @@ void RasterizationDrawCall::execute(bool restoreState) const {
}
break;
case TGL_QUADS:
for(int i = 0; i < cnt / 4; i++) {
for(int i = 0; i < cnt; i += 4) {
c->vertex[i + 2].edge_flag = 0;
gl_draw_triangle(c, &c->vertex[i], &c->vertex[i + 1], &c->vertex[i + 2]);
c->vertex[i + 2].edge_flag = 1;