View difference between Paste ID: R7Daf8n5 and 6ysGygxp
SHOW: | | - or go back to the newest paste.
1
#include "Draw.h"
2-
#include <stdio.h>
2+
///vars to add to structs
3-
#include <stdlib.h>
3+
struct OGL_Texture{
4-
#include <cstring>
4+
	float bw,bh;//blit width/height if non pwr 2 textures
5-
using namespace std;
5+
};
6
struct OGL_Surface : OGL_Texture{
7
	float bw,bh;
8
};
9
10-
//OGL Texture//
10+
///Draw Funcs to replace (also replace "GL_TEXTURE_RECTANGLE_NV" with "GL_TEXTURE_2D")
11
bool IsPowerOfTwo(uint32_t x)
12-
OGL_Texture::OGL_Texture(){
12+
13-
	w=h=0;
13+
    return ((x & (x - 1)) == 0);
14-
	texture_generated = false;
14+
15-
	Texture_ID = 0;
15+
int HighestBit(uint32_t x)
16
{
17-
OGL_Texture::~OGL_Texture(){
17+
	if (IsPowerOfTwo(x)){return x;}
18-
	if (Texture_ID){glDeleteTextures(1,&Texture_ID);}//0 is not a valid texture id
18+
	uint32_t y = 1<<31;
19
	while (y>x){y=y>>1;}
20
 	return y<<1;
21
}
22
void OGL_Texture::gen_texture(uint16_t width, uint16_t height, uint8_t *PixData){
23
	if (width==0 || height==0){printf("ERROR! WIDTH OR HEIGHT OF TEXTURE == 0"); exit(1);}
24
	//delete old texture if existing
25
	if (texture_generated && Texture_ID){
26
		glDeleteTextures(1,&Texture_ID);
27
	}
28
	//Power of two texture support
29
	w = width;
30
	h = height;
31
	uint8_t *NewPixData = PixData;
32-
	glEnable(GL_TEXTURE_RECTANGLE_NV);
32+
	bool todelete = false;
33-
		glBindTexture(GL_TEXTURE_RECTANGLE_NV, Texture_ID);
33+
	if (!(IsPowerOfTwo(w) && IsPowerOfTwo(h))){
34
		uint32_t new_w = HighestBit(w);
35-
		glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, PixData);
35+
		uint32_t new_h = HighestBit(h);
36-
		glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
36+
		NewPixData = new uint8_t[new_w*new_h*4];
37-
		glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
37+
		memset(NewPixData,255, new_w*new_h*4);
38-
		glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
38+
		uint32_t pos1 = 0;
39-
		glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
39+
		uint32_t pos2 = 0;
40
		for (uint32_t y = 0; y<h; y++){
41
			for (uint32_t x = 0; x<w; x++){
42-
	glDisable(GL_TEXTURE_RECTANGLE_NV);
42+
				NewPixData[pos1]  = PixData[pos2];
43
				NewPixData[pos1+1]= PixData[pos2+1];
44
				NewPixData[pos1+2]= PixData[pos2+2];
45
				NewPixData[pos1+3]= PixData[pos2+3];
46
				pos1+=4;
47
				pos2+=4;
48
			}
49
			pos1+=(new_w-w)*4;
50-
OGL_Surface::OGL_Surface(){
50+
51-
	texture_generated = false;
51+
		width= new_w;
52-
	bpp=4;
52+
		height= new_h;
53-
	w=h=0;
53+
		bw = float(w)/float(new_w);
54-
	PixData = nullptr;
54+
		bh = float(h)/float(new_h);
55
		todelete = true;
56-
OGL_Surface::~OGL_Surface(){
56+
57
	//generate texture
58
	glGenTextures(1,&Texture_ID);
59
	if (Texture_ID==0){printf("ERROR IN TEXTURE GENERATION! NO DEVICE CONTEXT?"); exit(1);}
60
	glEnable(GL_TEXTURE_2D);
61
		glBindTexture(GL_TEXTURE_2D, Texture_ID);
62
		//2d texture, level of detail, number of components (3=rgb), w,h, border, byte order, data format, data
63
		glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA8, width, height, 0, GL_BGRA,GL_UNSIGNED_BYTE, NewPixData);
64
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
65
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
66
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
67
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
68
		glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
69
		glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
70
	glDisable(GL_TEXTURE_2D);
71
	texture_generated = true;
72
	//cleanup
73
	if (todelete){delete [] NewPixData;}
74
}
75
76-
void OGL_Surface::Clear_Surface(uint8_t r, uint8_t g, uint8_t b, uint8_t a){
76+
77-
	if (r == g && g == b && bpp==3){
77+
78-
		memset(PixData, r, w*h*bpp);
78+
79
void OGL_Surface::Create_Surface(uint16_t set_w,uint16_t set_h, char set_bpp){
80-
	else if (r == g && g == b && b == a && bpp==4){
80+
81-
		memset(PixData, r, w*h*bpp);
81+
82
	// if surface already exists and width or height change delete old texture
83-
	else{
83+
84-
		unsigned int pos = 0;
84+
85-
		while (pos<w*h*bpp){
85+
86-
			PixData[pos++] = r;
86+
87-
			PixData[pos++] = g;
87+
88-
			PixData[pos++] = b;
88+
89-
			if(bpp==4){PixData[pos++] = a;}
89+
90
	h = set_h;
91
	bpp = set_bpp;
92
	PixData = new uint8_t[w*h*bpp];
93-
void OGL_Surface::Set_Surface_AlphaKey(uint8_t r, uint8_t g, uint8_t b)
93+
94
	if (!(IsPowerOfTwo(w) && IsPowerOfTwo(h))){printf("WARNING: non pow two surface, may be slow\n");}
95-
	if(bpp!=4){printf("trying to set alphakey on bpp that does not support alpha\n");return;}
95+
96-
	int pos = 0;
96+
97-
	for (unsigned int y = 0; y<h; y++){
97+
98-
		for (unsigned int x = 0; x<w; x++){
98+
99-
			if ((PixData[pos]==r) && (PixData[pos+1]==b) && (PixData[pos+2] == b)){
99+
100-
				PixData[pos+3]= 0;//if colour = alphakey set alpha channel to 0
100+
101
	uint8_t *NewPixData = PixData;
102-
			pos+=4;
102+
	bool todelete = false;
103
	if (!(IsPowerOfTwo(w) && IsPowerOfTwo(h))){
104
		uint32_t new_w = HighestBit(w);
105
		uint32_t new_h = HighestBit(h);
106
		NewPixData = new uint8_t[new_w*new_h*4];
107
		memset(NewPixData,255, new_w*new_h*4);
108
		uint32_t pos1 = 0;
109
		uint32_t pos2 = 0;
110
		for (uint32_t y = 0; y<h; y++){
111
			for (uint32_t x = 0; x<w; x++){
112
				NewPixData[pos1]  = PixData[pos2];
113
				NewPixData[pos1+1]= PixData[pos2+1];
114
				NewPixData[pos1+2]= PixData[pos2+2];
115
				NewPixData[pos1+3]= PixData[pos2+3];
116-
	glEnable(GL_TEXTURE_RECTANGLE_NV);
116+
				pos1+=4;
117-
		glBindTexture(GL_TEXTURE_RECTANGLE_NV, Texture_ID);
117+
				pos2+=4;
118
			}
119
			pos1+=(new_w-w)*4;
120
		}
121
		width= new_w;
122
		height= new_h;
123-
				case 3: glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, GL_RGBA8, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, PixData); break;
123+
		bw = w/new_w;
124-
				case 4: glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, GL_RGBA8, width, height, 0, GL_BGRA,GL_UNSIGNED_BYTE, PixData); break;
124+
		bh = h/new_h;
125
		todelete = true;
126
	}
127
	//only generate a texture once
128
	if (!texture_generated){
129
		glGenTextures(1,&Texture_ID);
130
		if (Texture_ID==0){printf("ERROR IN TEXTURE GENERATION! NO DEVICE CONTEXT?"); exit(1);}
131
	}
132-
				case 3: glTexSubImage2D(GL_TEXTURE_RECTANGLE_NV, 0, 0, 0, width, height, GL_BGR, GL_UNSIGNED_BYTE, PixData); break;
132+
	glEnable(GL_TEXTURE_2D);
133-
				case 4: glTexSubImage2D(GL_TEXTURE_RECTANGLE_NV, 0, 0, 0, width, height, GL_BGRA,GL_UNSIGNED_BYTE, PixData); break;
133+
		glBindTexture(GL_TEXTURE_2D, Texture_ID);
134
		//glTexImage2D respecifies the entire texture, changing its size, deleting the previous data etc.
135
		//only do this if texture doesn't exist or if w/h change
136-
		glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
136+
137-
		glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
137+
138-
		glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
138+
139-
		glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
139+
				case 3: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, NewPixData); break;
140
				case 4: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_BGRA,GL_UNSIGNED_BYTE, NewPixData); break;
141
			}
142-
	glDisable(GL_TEXTURE_RECTANGLE_NV);
142+
143
		//glTexSubImage2D only modifies pixel data within the texture.
144
		//do this when pixels need to be updated
145
		else{
146-
OGL_Texture *Texture_Cast(OGL_Surface *Surface)
146+
147
				//2d texture, level of detail, xoffset,yoffset, w,h,  byte order, data format, data
148-
	OGL_Texture *Texture = static_cast<OGL_Texture*>(Surface);
148+
				case 3: glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_BGR, GL_UNSIGNED_BYTE, NewPixData); break;
149-
	Texture->w = Surface->w;
149+
				case 4: glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_BGRA,GL_UNSIGNED_BYTE, NewPixData); break;
150-
	Texture->h = Surface->h;
150+
151-
	return Texture;
151+
152
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
153
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
154
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
155
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
156
		glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
157
		glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
158
	glDisable(GL_TEXTURE_2D);
159
	texture_generated = true;
160
	//cleanup
161
	if (todelete){delete [] NewPixData;}
162
}
163
//BLIT//
164
////////
165
//glBlendFunc(source_blend, dst_blend)
166
//GL_ZERO						colour is ignored
167
//GL_ONE						full colour is taken into addition
168
//GL_(DST/SRC)_COLOR			colour is multiplied by (DST/SRC) color
169
//GL_ONE_MINUS_(DST/SRC)_COLOR	colour is multiplied by inverted (DST/SRC) color
170
//GL_(DST/SRC)_ALPHA			colour is multiplied by (DST/SRC) alpha value
171
//GL_ONE_MINUS_(DST/SRC)_ALPHA	colour is multiplied by inverted (DST/SRC) alpha value
172
//overall colour (GL_SRC_ALPHA, GL_ONE) -addative- = (r1*a1,g1*a1,b1*a1)+(r2,g2,b2)
173
void DrawImage(OGL_Texture *Texture, int dx, int dy, float rot,float scale_x,float scale_y,float alpha,int options){
174
	if (options & IMG_HFLIP){dx+=Texture->w; scale_x=-1;}
175
	if (options & IMG_VFLIP){dy+=Texture->h; scale_y=-1;}
176
	glLoadIdentity();
177
	glTranslatef(dx, dy, 0.0);
178-
	glEnable(GL_TEXTURE_RECTANGLE_NV);
178+
179-
		glEnable(GL_BLEND);
179+
180-
			//additive blending - gray + gray = white
180+
181-
			if (options &= IMG_ADD_BLEND){glBlendFunc(GL_SRC_ALPHA, GL_ONE);}
181+
182-
			//regular alpha blending - gray + gray = gray
182+
183-
			else{glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);}
183+
184-
			//blit
184+
185-
			glColor4f(1.0f, 1.0f, 1.0f, alpha);
185+
186-
			glBindTexture(GL_TEXTURE_RECTANGLE_NV, Texture->Texture_ID);
186+
	glEnable(GL_TEXTURE_2D);
187-
			glBegin(GL_QUADS);
187+
	glEnable(GL_BLEND);
188-
				glTexCoord2i(0,0);
188+
		//additive blending - gray + gray = white
189-
				glVertex2i(0, 0);
189+
		if (options &= IMG_ADD_BLEND){glBlendFunc(GL_SRC_ALPHA, GL_ONE);}
190-
				glTexCoord2i(Texture->w,0);
190+
		//regular alpha blending - gray + gray = gray
191-
				glVertex2i(Texture->w, 0);
191+
		else{glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);}
192-
				glTexCoord2i(Texture->w,Texture->h);
192+
		//blit
193-
				glVertex2i(Texture->w, Texture->h);
193+
		glColor4f(1.0f, 1.0f, 1.0f, alpha);
194-
				glTexCoord2i(0,Texture->h);
194+
		glBindTexture(GL_TEXTURE_2D, Texture->Texture_ID);
195-
				glVertex2i(0, Texture->h);
195+
		glBegin(GL_QUADS);
196-
			glEnd();
196+
			glTexCoord2f(0,0);
197-
		glDisable(GL_BLEND);
197+
			glVertex2d(0, 0);
198-
	glDisable(GL_TEXTURE_RECTANGLE_NV);
198+
			glTexCoord2f(Texture->bw,0);
199
			glVertex2d(Texture->w, 0);
200
			glTexCoord2f(Texture->bw,Texture->bh);
201
			glVertex2d(Texture->w, Texture->h);
202
			glTexCoord2f(0,Texture->bh);
203
			glVertex2d(0, Texture->h);
204
		glEnd();
205
	glDisable(GL_BLEND);
206
	glDisable(GL_TEXTURE_2D);
207
	glLoadIdentity();
208
}
209
void DrawSubImage(OGL_Texture *Texture, int sx, int sy, int sw, int sh, int dx, int dy, float rot,float scale_x,float scale_y,float alpha,int options){
210
	float tex_coord_x1 = (float)sx/(float)Texture->w;
211
	float tex_coord_y1 = (float)sy/(float)Texture->h;
212
	float tex_coord_x2 = tex_coord_x1+((float)sw/(float)Texture->w);
213
	float tex_coord_y2 = tex_coord_y1+((float)sh/(float)Texture->h);
214-
	glEnable(GL_TEXTURE_RECTANGLE_NV);
214+
	tex_coord_x1 *= Texture->bw;
215-
		glEnable(GL_BLEND);
215+
	tex_coord_y1 *= Texture->bh;
216-
			//additive blending - gray + gray = white
216+
	tex_coord_x2 *= Texture->bw;
217-
			if (options &= IMG_ADD_BLEND){glBlendFunc(GL_SRC_ALPHA, GL_ONE);}
217+
	tex_coord_y2 *= Texture->bh;
218-
			//regular alpha blending - gray + gray = gray
218+
219-
			else{glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);}
219+
220-
			//blit
220+
221-
			glColor4f(1.0,1.0,1.0,alpha);
221+
222-
			glBindTexture(GL_TEXTURE_RECTANGLE_NV, Texture->Texture_ID);
222+
223-
			glBegin(GL_QUADS);
223+
224-
				glTexCoord2i(sx,sy);
224+
225-
				glVertex2i(0, 0);
225+
226-
				glTexCoord2i(sx+sw,sy);
226+
227-
				glVertex2i(sw, 0);
227+
228-
				glTexCoord2i(sx+sw,sy+sh);
228+
229-
				glVertex2i(sw, sh);
229+
230-
				glTexCoord2i(sx,sy+sh);
230+
	glEnable(GL_TEXTURE_2D);
231-
				glVertex2i(0, sh);
231+
	glEnable(GL_BLEND);
232-
			glEnd();
232+
		//additive blending - gray + gray = white
233-
		glDisable(GL_BLEND);
233+
		if (options &= IMG_ADD_BLEND){glBlendFunc(GL_SRC_ALPHA, GL_ONE);}
234-
	glDisable(GL_TEXTURE_RECTANGLE_NV);
234+
		//regular alpha blending - gray + gray = gray
235
		else{glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);}
236
		//blit
237
		glColor4f(1.0,1.0,1.0,alpha);
238-
//////////
238+
		glBindTexture(GL_TEXTURE_2D, Texture->Texture_ID);
239-
//COLOUR//
239+
		glBegin(GL_QUADS);
240-
//////////
240+
			glTexCoord2f(tex_coord_x1,tex_coord_y1);
241-
uint32_t make_col(uint8_t r, uint8_t g, uint8_t b, uint8_t a){
241+
			glVertex2d(0, 0);
242-
	uint32_t col = 0;
242+
			glTexCoord2f(tex_coord_x2,tex_coord_y1);
243-
	col |= r;
243+
			glVertex2d(sw, 0);
244-
	col |= uint32_t(g)<<8;
244+
			glTexCoord2f(tex_coord_x2,tex_coord_y2);
245-
	col |= uint32_t(b)<<16;
245+
			glVertex2d(sw, sh);
246-
	col |= uint32_t(a)<<24;
246+
			glTexCoord2f(tex_coord_x1,tex_coord_y2);
247-
	//printf("%#X, %d,%d,%d\n", col,r,g,b);
247+
			glVertex2d(0, sh);
248-
	return col;
248+
		glEnd();
249
	glDisable(GL_BLEND);
250
	glDisable(GL_TEXTURE_2D);
251-
uint32_t make_col(uint8_t r, uint8_t g, uint8_t b){
251+
252-
	return make_col(r,g,b,255);
252+