1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2024-06-18 11:19:59 +00:00

drawing textures without OpenGL

This commit is contained in:
Zeno Rogue 2017-12-19 00:39:11 +01:00
parent 20ef4b1c9f
commit 168d35cb17
3 changed files with 57 additions and 16 deletions

View File

@ -1967,7 +1967,7 @@ struct textureinfo {
vector<GLfloat> vertices;
vector<GLfloat> tvertices;
cell *c;
vector<transmatrix> matrices;
vector<transmatrix> matrices;
// these are required to adjust to geometry changes
int current_geometry, current_type, symmetries, current_trunc;
@ -2380,6 +2380,8 @@ namespace texture {
extern unsigned paint_color;
extern ld penwidth;
extern transmatrix itt;
extern int twidth;
extern vector<unsigned> texture_pixels;
void showMenu();

View File

@ -246,13 +246,40 @@ void polylineColor(SDL_Surface *s, int *x, int *y, int polyi, int col) {
lineColor(s, x[i-1], y[i-1], x[i], y[i], col);
}
void filledPolygonColorI(SDL_Surface *s, int* polyx, int *polyy, int polyi, int col) {
Sint16 spolyx[polyi], spolyy[polyi];
for(int i=0; i<polyi; i++) spolyx[i] = polyx[i], spolyy[i] = polyy[i];
filledPolygonColor(s, spolyx, spolyy, polyi, col);
void filledPolygonColorI(SDL_Surface *s, int* px, int *py, int polyi, int col) {
Sint16 spx[polyi], spy[polyi];
for(int i=0; i<polyi; i++) spx[i] = px[i], spy[i] = py[i];
filledPolygonColor(s, spx, spy, polyi, col);
}
#endif
void drawTexturedTriangle(SDL_Surface *s, int *px, int *py, GLfloat *tv, int col) {
transmatrix source = {{{ld(px[0]),ld(px[1]),ld(px[2])}, {ld(py[0]),ld(py[1]),ld(py[2])}, {1,1,1}}};
transmatrix target = {{{tv[0],tv[3],tv[6]}, {tv[1],tv[4],tv[7]}, {1,1,1}}};
transmatrix isource = inverse(source);
int minx = px[0], maxx = px[0];
int miny = py[0], maxy = py[0];
for(int i=1; i<3; i++)
minx = min(minx, px[i]), maxx = max(maxx, px[i]),
miny = min(miny, py[i]), maxy = max(maxy, py[i]);
for(int mx=minx; mx<maxx; mx++)
for(int my=miny; my<maxy; my++) {
hyperpoint h = isource * hpxyz(mx, my, 1);
if(h[0] >= -1e-7 && h[1] >= -1e-7 && h[2] >= -1e-7) {
hyperpoint ht = target * h;
int x = int(ht[0] * texture::twidth) & (texture::twidth-1);
int y = int(ht[1] * texture::twidth) & (texture::twidth-1);
int c = texture::texture_pixels[y * texture::twidth + x];
auto& pix = qpixel(s, mx, my);
for(int p=0; p<3; p++) {
int alpha = part(c, 3) * part(col, 0);
auto& v = part(pix, p);
v = ((255*255 - alpha) * 255 * v + alpha * part(col, p+1) * part(c, p) + 255 * 255 * 255/2 + 1) / (255 * 255 * 255);
}
}
}
}
#if CAP_GL
void glcolor2(int color) {
unsigned char *c = (unsigned char*) (&color);
@ -606,7 +633,12 @@ void drawpolyline(polytodraw& p) {
for(int i=0; i<polyi; i++) gdpush(polyx[i]), gdpush(polyy[i]);
#elif CAP_SDLGFX==1
if(poly_flags & POLY_INVERSE) {
if(pp.tinf) {
if(!(poly_flags & POLY_INVERSE))
for(int i=0; i<polyi; i += 3)
drawTexturedTriangle(s, polyx+i, polyy+i, &pp.tinf->tvertices[i*3], p.col);
}
else if(poly_flags & POLY_INVERSE) {
int i = polyi;
if(true) {
polyx[i] = 0; polyy[i] = 0; i++;

View File

@ -33,7 +33,7 @@ int twidth = 2048;
unsigned paint_color = 0x000000FF;
vector<int> expanded_data;
vector<unsigned> texture_pixels;
string texturename = "hyperrogue-texture.png";
string configname = "hyperrogue.txc";
@ -77,14 +77,14 @@ bool loadTextureGL() {
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, twidth, twidth, 0,
GL_BGRA, GL_UNSIGNED_BYTE,
&expanded_data[0] );
&texture_pixels[0] );
return true;
}
bool whitetexture() {
expanded_data.resize(0);
expanded_data.resize(twidth * twidth, 0xFFFFFFFF);
texture_pixels.resize(0);
texture_pixels.resize(twidth * twidth, 0xFFFFFFFF);
return true;
}
@ -102,7 +102,7 @@ bool readtexture() {
SDL_FreeSurface(txt);
vector<int> half_expanded(twidth * ty);
expanded_data.resize(twidth * twidth);
texture_pixels.resize(twidth * twidth);
int origdim = max(tx, ty);
int base_x = tx/2 - origdim/2;
@ -112,12 +112,12 @@ bool readtexture() {
/* for(int y=0; y<twidth; y++)
for(int x=0; x<twidth; x++)
expanded_data[y*twidth+x] = qpixel(txt2, y%ty, x%tx); */
texture_pixels[y*twidth+x] = qpixel(txt2, y%ty, x%tx); */
for(int x=0; x<twidth; x++)
scale_colorarray(origdim,
[&] (int y) { return base_y+y < 0 || base_y+y >= ty ? 0 : half_expanded[x + (base_y + y) * twidth]; },
[&] (int y, int v) { expanded_data[twidth * y + x] = v; }
[&] (int y, int v) { texture_pixels[twidth * y + x] = v; }
);
for(int y=0; y<ty; y++)
@ -198,8 +198,8 @@ void mapTexture(cell *c, textureinfo& mi, patterns::patterninfo &si, const trans
}
int recolor(int col) {
if(color_alpha == 255 || (cmode & sm::DRAW)) return col | 0xFFFFFF00;
if(color_alpha == 0) return col;
if(color_alpha == 255) return col | 0xFFFFFF00;
for(int i=1; i<4; i++)
part(col, i) = color_alpha + ((255-color_alpha) * part(col,i) + 127) / 255;
return col;
@ -630,6 +630,8 @@ void showMenu() {
dialog::addSelItem(XLAT("reactivate the texture"), texturename, 't');
dialog::addSelItem(XLAT("open texture file"), texturename, 'o');
dialog::addSelItem(XLAT("load texture config"), "...", 'l');
dialog::addSelItem(XLAT("texture size"), its(twidth), 'w');
dialog::addSelItem(XLAT("paint a new texture"), "...", 'n');
}
if(tstate == tsAdjusting) {
@ -749,6 +751,12 @@ void showMenu() {
else return false;
});
else if(uni == 'w' && tstate == tsOff) {
twidth *= 2;
if(twidth > 9000) twidth = 256;
tstate_max = tsOff;
}
else if(uni == 'n' && tstate == tsOff) {
addMessage("white");
if(whitetexture() && loadTextureGL()) {
@ -839,7 +847,7 @@ void filltriangle(const array<hyperpoint, 3>& v, const array<point, 3>& p, int c
if((d0 <= 1 && d1 <= 1 && d2 <= 1) || lev >= 20) {
for(int i=0; i<3; i++)
expanded_data[((p[i].first) & (twidth-1)) + (p[i].second & (twidth-1)) * twidth] = col;
texture_pixels[((p[i].first) & (twidth-1)) + (p[i].second & (twidth-1)) * twidth] = col;
return;
}
else if(d1 >= d0 && d1 >= d2)
@ -903,6 +911,5 @@ void drawPixel(cell *c, hyperpoint h, int col) {
}
// todo texture editor
// todo `three octagons` with two colors