OpenGL: remove non-power-of-two texture check, where even ES 2.0 does not need it.

This commit is contained in:
Brecht Van Lommel
2015-12-06 21:41:21 +01:00
parent af5784312a
commit b25e4b310f
15 changed files with 180 additions and 310 deletions

View File

@@ -170,8 +170,8 @@ static void blf_glyph_cache_texture(FontBLF *font, GlyphCacheBLF *gc)
glGenTextures(1, &gc->textures[gc->cur_tex]);
glBindTexture(GL_TEXTURE_2D, (font->tex_bind_state = gc->textures[gc->cur_tex]));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

View File

@@ -627,7 +627,7 @@ static void init_internal_icons(void)
}
/* we only use a texture for cards with non-power of two */
if (GPU_non_power_of_two_support()) {
if (GPU_full_non_power_of_two_support()) {
glGenTextures(1, &icongltex.id);
if (icongltex.id) {

View File

@@ -8039,13 +8039,13 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
if (!sds->wt || !(sds->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) {
sds->tex = NULL;
GPU_create_smoke(smd, 0);
draw_smoke_volume(sds, ob, p0, p1, sds->res, viewnormal);
draw_smoke_volume(sds, ob, p0, p1, viewnormal);
GPU_free_smoke(smd);
}
else if (sds->wt && (sds->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) {
sds->tex = NULL;
GPU_create_smoke(smd, 1);
draw_smoke_volume(sds, ob, p0, p1, sds->res_wt, viewnormal);
draw_smoke_volume(sds, ob, p0, p1, viewnormal);
GPU_free_smoke(smd);
}

View File

@@ -135,9 +135,9 @@ static GPUTexture *create_flame_spectrum_texture(void)
void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob,
const float min[3], const float max[3],
const int res[3], const float viewnormal[3])
const float viewnormal[3])
{
GPUTexture *tex_spec;
GPUTexture *tex_spec = NULL;
GPUProgram *smoke_program;
const int progtype = (sds->active_fields & SM_ACTIVE_COLORS) ? GPU_PROGRAM_SMOKE_COLORED
: GPU_PROGRAM_SMOKE;
@@ -152,7 +152,6 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob,
float d /*, d0 */ /* UNUSED */, dd, ds;
float (*points)[3] = NULL;
int numpoints = 0;
float cor[3] = {1.0f, 1.0f, 1.0f};
int gl_depth = 0, gl_blend = 0;
const bool use_fire = (sds->active_fields & SM_ACTIVE_FIRE) != 0;
@@ -171,6 +170,7 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob,
};
const float size[3] = { max[0] - min[0], max[1] - min[1], max[2] - min[2] };
const float invsize[3] = { 1.0f / size[0], 1.0f / size[1], 1.0f / size[2] };
/* edges have the form edges[n][0][xyz] + t*edges[n][1][xyz] */
const float edges[12][2][3] = {
@@ -257,16 +257,6 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob,
GPU_texture_bind(tex_spec, 3);
}
if (!GPU_non_power_of_two_support()) {
cor[0] = (float)res[0] / (float)power_of_2_max_u(res[0]);
cor[1] = (float)res[1] / (float)power_of_2_max_u(res[1]);
cor[2] = (float)res[2] / (float)power_of_2_max_u(res[2]);
}
cor[0] /= size[0];
cor[1] /= size[1];
cor[2] /= size[2];
/* our slices are defined by the plane equation a*x + b*y +c*z + d = 0
* (a,b,c), the plane normal, are given by viewdir
* d is the parameter along the view direction. the first d is given by
@@ -318,9 +308,9 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob,
GPU_program_parameter_4f(smoke_program, 2, 1.0, 0.0, 0.0, 0.0);
glBegin(GL_POLYGON);
for (i = 0; i < numpoints; i++) {
glTexCoord3d((points[i][0] - min[0]) * cor[0],
(points[i][1] - min[1]) * cor[1],
(points[i][2] - min[2]) * cor[2]);
glTexCoord3d((points[i][0] - min[0]) * invsize[0],
(points[i][1] - min[1]) * invsize[1],
(points[i][2] - min[2]) * invsize[2]);
glVertex3f(points[i][0] * ob_sizei[0],
points[i][1] * ob_sizei[1],
points[i][2] * ob_sizei[2]);
@@ -334,9 +324,9 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob,
GPU_program_parameter_4f(smoke_program, 2, -1.0, 0.0, 0.0, 0.0);
glBegin(GL_POLYGON);
for (i = 0; i < numpoints; i++) {
glTexCoord3d((points[i][0] - min[0]) * cor[0],
(points[i][1] - min[1]) * cor[1],
(points[i][2] - min[2]) * cor[2]);
glTexCoord3d((points[i][0] - min[0]) * invsize[0],
(points[i][1] - min[1]) * invsize[1],
(points[i][2] - min[2]) * invsize[2]);
glVertex3f(points[i][0] * ob_sizei[0],
points[i][1] * ob_sizei[1],
points[i][2] * ob_sizei[2]);

View File

@@ -274,7 +274,7 @@ extern const char *view3d_context_dir[]; /* doc access */
/* draw_volume.c */
void draw_smoke_volume(struct SmokeDomainSettings *sds, struct Object *ob,
const float min[3], const float max[3],
const int res[3], const float viewnormal[3]);
const float viewnormal[3]);
//#define SMOKE_DEBUG_VELOCITY
//#define SMOKE_DEBUG_HEAT

View File

@@ -61,7 +61,7 @@ void GPU_extensions_disable(void);
bool GPU_legacy_support(void);
bool GPU_glsl_support(void);
bool GPU_non_power_of_two_support(void);
bool GPU_full_non_power_of_two_support(void);
bool GPU_display_list_support(void);
bool GPU_bicubic_bump_support(void);
bool GPU_geometry_shader_support(void);
@@ -107,9 +107,7 @@ bool GPU_type_matches(GPUDeviceType device, GPUOSType os, GPUDriverType driver);
* - always returns unsigned char RGBA textures
* - if texture with non square dimensions is created, depending on the
* graphics card capabilities the texture may actually be stored in a
* larger texture with power of two dimensions. the actual dimensions
* may be queried with GPU_texture_opengl_width/height. GPU_texture_coord_2f
* calls glTexCoord2f with the coordinates adjusted for this.
* larger texture with power of two dimensions.
* - can use reference counting:
* - reference counter after GPU_texture_create is 1
* - GPU_texture_ref increases by one
@@ -151,8 +149,8 @@ void GPU_texture_filter_mode(GPUTexture *tex, bool compare, bool use_filter);
GPUFrameBuffer *GPU_texture_framebuffer(GPUTexture *tex);
int GPU_texture_target(const GPUTexture *tex);
int GPU_texture_opengl_width(const GPUTexture *tex);
int GPU_texture_opengl_height(const GPUTexture *tex);
int GPU_texture_width(const GPUTexture *tex);
int GPU_texture_height(const GPUTexture *tex);
int GPU_texture_opengl_bindcode(const GPUTexture *tex);
/* GPU Framebuffer

View File

@@ -304,7 +304,7 @@ bool GPU_fx_compositor_initialize_passes(
fx->effects = 0;
if (!GPU_non_power_of_two_support() || !GLEW_EXT_framebuffer_object)
if (!GLEW_EXT_framebuffer_object)
return false;
if (!fx_settings) {
@@ -1082,12 +1082,12 @@ bool GPU_fx_do_composite_pass(GPUFX *fx, float projmat[4][4], bool is_persp, str
{
int invrendertargetdim_uniform, color_uniform, depth_uniform, dof_uniform;
int viewvecs_uniform;
float invrendertargetdim[2] = {1.0f / GPU_texture_opengl_width(fx->dof_near_coc_blurred_buffer),
1.0f / GPU_texture_opengl_height(fx->dof_near_coc_blurred_buffer)};
float invrendertargetdim[2] = {1.0f / GPU_texture_width(fx->dof_near_coc_blurred_buffer),
1.0f / GPU_texture_height(fx->dof_near_coc_blurred_buffer)};
float tmp = invrendertargetdim[0];
invrendertargetdim[0] = 0.0f;
dof_params[2] = GPU_texture_opengl_width(fx->dof_near_coc_blurred_buffer) / (scale_camera * fx_dof->sensor);
dof_params[2] = GPU_texture_width(fx->dof_near_coc_blurred_buffer) / (scale_camera * fx_dof->sensor);
dof_uniform = GPU_shader_get_uniform(dof_shader_pass2, "dof_params");
invrendertargetdim_uniform = GPU_shader_get_uniform(dof_shader_pass2, "invrendertargetdim");
@@ -1174,8 +1174,8 @@ bool GPU_fx_do_composite_pass(GPUFX *fx, float projmat[4][4], bool is_persp, str
{
int near_coc_downsampled;
int invrendertargetdim_uniform;
float invrendertargetdim[2] = {1.0f / GPU_texture_opengl_width(fx->dof_near_coc_blurred_buffer),
1.0f / GPU_texture_opengl_height(fx->dof_near_coc_blurred_buffer)};
float invrendertargetdim[2] = {1.0f / GPU_texture_width(fx->dof_near_coc_blurred_buffer),
1.0f / GPU_texture_height(fx->dof_near_coc_blurred_buffer)};
near_coc_downsampled = GPU_shader_get_uniform(dof_shader_pass4, "colorbuffer");
invrendertargetdim_uniform = GPU_shader_get_uniform(dof_shader_pass4, "invrendertargetdim");

View File

@@ -730,7 +730,7 @@ void GPU_create_gl_tex(unsigned int *bind, unsigned int *rect, float *frect, int
/* scale if not a power of two. this is not strictly necessary for newer
* GPUs (OpenGL version >= 2.0) since they support non-power-of-two-textures
* Then don't bother scaling for hardware that supports NPOT textures! */
if ((!GPU_non_power_of_two_support() && !is_power_of_2_resolution(rectw, recth)) ||
if ((!GPU_full_non_power_of_two_support() && !is_power_of_2_resolution(rectw, recth)) ||
is_over_resolution_limit(rectw, recth)) {
rectw = smaller_power_of_2_limit(rectw);
recth = smaller_power_of_2_limit(recth);
@@ -1000,7 +1000,7 @@ void GPU_paint_set_mipmap(bool mipmap)
/* check if image has been downscaled and do scaled partial update */
static bool GPU_check_scaled_image(ImBuf *ibuf, Image *ima, float *frect, int x, int y, int w, int h)
{
if ((!GPU_non_power_of_two_support() && !is_power_of_2_resolution(ibuf->x, ibuf->y)) ||
if ((!GPU_full_non_power_of_two_support() && !is_power_of_2_resolution(ibuf->x, ibuf->y)) ||
is_over_resolution_limit(ibuf->x, ibuf->y))
{
int x_limit = smaller_power_of_2_limit(ibuf->x);

View File

@@ -293,9 +293,10 @@ bool GPU_glsl_support(void)
return true;
}
bool GPU_non_power_of_two_support(void)
bool GPU_full_non_power_of_two_support(void)
{
/* always supported on full GL but still relevant for OpenGL ES */
/* always supported on full GL but still relevant for OpenGL ES 2.0 where
* NPOT textures can't use mipmaps or repeat wrap mode */
return true;
}
@@ -384,7 +385,6 @@ static void GPU_print_framebuffer_error(GLenum status, char err_out[256])
struct GPUTexture {
int w, h; /* width/height */
int w_orig, h_orig; /* width/height (before power of 2 is applied) */
int number; /* number for multitexture binding */
int refcount; /* reference count */
GLenum target; /* GL_TEXTURE_* */
@@ -395,7 +395,6 @@ struct GPUTexture {
GPUFrameBuffer *fb; /* GPUFramebuffer this texture is attached to */
int fb_attachment; /* slot the texture is attached to */
int depth; /* is a depth texture? if 3D how deep? */
int depth_orig; /* depth (before power of 2 is applied) */
};
static unsigned char *GPU_texture_convert_pixels(int length, const float *fpixels)
@@ -439,13 +438,13 @@ static GPUTexture *GPU_texture_create_nD(
}
tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture");
tex->w = tex->w_orig = w;
tex->h = tex->h_orig = h;
tex->w = w;
tex->h = h;
tex->number = -1;
tex->refcount = 1;
tex->target = (n == 1) ? GL_TEXTURE_1D : (samples ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D);
tex->target_base = (n == 1) ? GL_TEXTURE_1D : GL_TEXTURE_2D;
tex->depth = tex->depth_orig = depth;
tex->depth = depth;
tex->fb_attachment = -1;
glGenTextures(1, &tex->bindcode);
@@ -463,7 +462,7 @@ static GPUTexture *GPU_texture_create_nD(
return NULL;
}
if (!GPU_non_power_of_two_support()) {
if (!GPU_full_non_power_of_two_support()) {
tex->w = power_of_2_max_i(tex->w);
tex->h = power_of_2_max_i(tex->h);
}
@@ -587,9 +586,9 @@ GPUTexture *GPU_texture_create_3D(int w, int h, int depth, int channels, const f
bool rescale = false;
tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture");
tex->w = tex->w_orig = w;
tex->h = tex->h_orig = h;
tex->depth = tex->depth_orig = depth;
tex->w = w;
tex->h = h;
tex->depth = depth;
tex->number = -1;
tex->refcount = 1;
tex->target = GL_TEXTURE_3D;
@@ -604,12 +603,6 @@ GPUTexture *GPU_texture_create_3D(int w, int h, int depth, int channels, const f
return NULL;
}
if (!GPU_non_power_of_two_support()) {
tex->w = power_of_2_max_i(tex->w);
tex->h = power_of_2_max_i(tex->h);
tex->depth = power_of_2_max_i(tex->depth);
}
tex->number = 0;
glBindTexture(tex->target, tex->bindcode);
@@ -687,18 +680,7 @@ GPUTexture *GPU_texture_create_3D(int w, int h, int depth, int channels, const f
}
else {
if (fpixels) {
if (!GPU_non_power_of_two_support() && (w != tex->w || h != tex->h || depth != tex->depth)) {
/* clear first to avoid unitialized pixels */
float *zero= MEM_callocN(sizeof(float)*tex->w*tex->h*tex->depth, "zero");
glTexImage3D(tex->target, 0, internalformat, tex->w, tex->h, tex->depth, 0, format, type, NULL);
glTexSubImage3D(tex->target, 0, 0, 0, 0, tex->w, tex->h, tex->depth, GL_INTENSITY, GL_FLOAT, zero);
glTexSubImage3D(tex->target, 0, 0, 0, 0, w, h, depth, format, type, fpixels);
MEM_freeN(zero);
}
else {
glTexImage3D(tex->target, 0, internalformat, tex->w, tex->h, tex->depth, 0, format, type, fpixels);
}
glTexImage3D(tex->target, 0, internalformat, tex->w, tex->h, tex->depth, 0, format, type, fpixels);
GPU_ASSERT_NO_GL_ERRORS("3D glTexSubImage3D");
}
}
@@ -752,8 +734,8 @@ GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, bool is_data,
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_BORDER, &border);
tex->w = tex->w_orig = w - border;
tex->h = tex->h_orig = h - border;
tex->w = w - border;
tex->h = h - border;
}
glBindTexture(GL_TEXTURE_2D, 0);
@@ -797,8 +779,8 @@ GPUTexture *GPU_texture_from_preview(PreviewImage *prv, int mipmap)
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h);
tex->w = tex->w_orig = w;
tex->h = tex->h_orig = h;
tex->w = w;
tex->h = h;
}
glBindTexture(GL_TEXTURE_2D, 0);
@@ -1065,12 +1047,12 @@ int GPU_texture_target(const GPUTexture *tex)
return tex->target;
}
int GPU_texture_opengl_width(const GPUTexture *tex)
int GPU_texture_width(const GPUTexture *tex)
{
return tex->w;
}
int GPU_texture_opengl_height(const GPUTexture *tex)
int GPU_texture_height(const GPUTexture *tex)
{
return tex->h;
}
@@ -1226,7 +1208,7 @@ void GPU_texture_bind_as_framebuffer(GPUTexture *tex)
}
/* push matrices and set default viewport and matrix */
glViewport(0, 0, tex->w_orig, tex->h_orig);
glViewport(0, 0, tex->w, tex->h);
GG.currentfb = tex->fb->object;
glMatrixMode(GL_PROJECTION);
@@ -1264,7 +1246,7 @@ void GPU_framebuffer_slots_bind(GPUFrameBuffer *fb, int slot)
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT + slot);
/* push matrices and set default viewport and matrix */
glViewport(0, 0, fb->colortex[slot]->w_orig, fb->colortex[slot]->h_orig);
glViewport(0, 0, fb->colortex[slot]->w, fb->colortex[slot]->h);
GG.currentfb = fb->object;
glMatrixMode(GL_PROJECTION);
@@ -1294,7 +1276,7 @@ void GPU_framebuffer_bind_no_save(GPUFrameBuffer *fb, int slot)
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT + slot);
/* push matrices and set default viewport and matrix */
glViewport(0, 0, fb->colortex[slot]->w_orig, fb->colortex[slot]->h_orig);
glViewport(0, 0, fb->colortex[slot]->w, fb->colortex[slot]->h);
GG.currentfb = fb->object;
GG.currentfb = fb->object;
}
@@ -1354,8 +1336,8 @@ void GPU_framebuffer_restore(void)
void GPU_framebuffer_blur(GPUFrameBuffer *fb, GPUTexture *tex, GPUFrameBuffer *blurfb, GPUTexture *blurtex)
{
const float scaleh[2] = {1.0f / blurtex->w_orig, 0.0f};
const float scalev[2] = {0.0f, 1.0f / tex->h_orig};
const float scaleh[2] = {1.0f / blurtex->w, 0.0f};
const float scalev[2] = {0.0f, 1.0f / tex->h};
GPUShader *blur_shader = GPU_shader_get_builtin_shader(GPU_SHADER_SEP_GAUSSIAN_BLUR);
int scale_uniform, texture_source_uniform;
@@ -1379,7 +1361,7 @@ void GPU_framebuffer_blur(GPUFrameBuffer *fb, GPUTexture *tex, GPUFrameBuffer *b
GPU_shader_bind(blur_shader);
GPU_shader_uniform_vector(blur_shader, scale_uniform, 2, 1, scaleh);
GPU_shader_uniform_texture(blur_shader, texture_source_uniform, tex);
glViewport(0, 0, blurtex->w_orig, blurtex->h_orig);
glViewport(0, 0, blurtex->w, blurtex->h);
/* Peparing to draw quad */
glMatrixMode(GL_MODELVIEW);
@@ -1408,7 +1390,7 @@ void GPU_framebuffer_blur(GPUFrameBuffer *fb, GPUTexture *tex, GPUFrameBuffer *b
GG.currentfb = fb->object;
glViewport(0, 0, tex->w_orig, tex->h_orig);
glViewport(0, 0, tex->w, tex->h);
GPU_shader_uniform_vector(blur_shader, scale_uniform, 2, 1, scalev);
GPU_shader_uniform_texture(blur_shader, texture_source_uniform, blurtex);
GPU_texture_bind(blurtex, 0);
@@ -1523,8 +1505,8 @@ void GPU_offscreen_unbind(GPUOffScreen *ofs, bool restore)
void GPU_offscreen_read_pixels(GPUOffScreen *ofs, int type, void *pixels)
{
const int w = ofs->color->w_orig;
const int h = ofs->color->h_orig;
const int w = ofs->color->w;
const int h = ofs->color->h;
if (ofs->color->target == GL_TEXTURE_2D_MULTISAMPLE) {
/* For a multi-sample texture,
@@ -1602,12 +1584,12 @@ finally:
int GPU_offscreen_width(const GPUOffScreen *ofs)
{
return ofs->color->w_orig;
return ofs->color->w;
}
int GPU_offscreen_height(const GPUOffScreen *ofs)
{
return ofs->color->h_orig;
return ofs->color->h;
}
int GPU_offscreen_color_texture(const GPUOffScreen *ofs)

View File

@@ -2310,7 +2310,7 @@ GPUShaderExport *GPU_shader_export(struct Scene *scene, struct Material *ma)
if (GPU_texture_opengl_bindcode(input->tex)) {
uniform->type = GPU_DYNAMIC_SAMPLER_2DBUFFER;
glBindTexture(GL_TEXTURE_2D, GPU_texture_opengl_bindcode(input->tex));
uniform->texsize = GPU_texture_opengl_width(input->tex) * GPU_texture_opengl_height(input->tex);
uniform->texsize = GPU_texture_width(input->tex) * GPU_texture_height(input->tex);
uniform->texpixels = MEM_mallocN(uniform->texsize*4, "RGBApixels");
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, uniform->texpixels);
glBindTexture(GL_TEXTURE_2D, 0);

View File

@@ -355,67 +355,15 @@ static void wm_method_draw_overlap_all(bContext *C, wmWindow *win, int exchange)
}
}
#if 0
/******************** draw damage ************************/
/* - not implemented */
static void wm_method_draw_damage(bContext *C, wmWindow *win)
{
wm_method_draw_all(C, win);
}
#endif
/****************** draw triple buffer ********************/
/* - area regions are written into a texture, without any */
/* of the overlapping menus, brushes, gestures. these */
/* are redrawn each time. */
/* */
/* - if non-power of two textures are supported, that is */
/* used. if not, multiple smaller ones are used, with */
/* worst case wasted space being 23.4% for 3x3 textures */
static void split_width(int x, int n, int *splitx, int *nx)
{
int a, newnx, waste;
/* if already power of two just use it */
if (is_power_of_2_i(x)) {
splitx[0] = x;
(*nx)++;
return;
}
if (n == 1) {
/* last part, we have to go larger */
splitx[0] = power_of_2_max_i(x);
(*nx)++;
}
else {
/* two or more parts to go, use smaller part */
splitx[0] = power_of_2_min_i(x);
newnx = ++(*nx);
split_width(x - splitx[0], n - 1, splitx + 1, &newnx);
for (waste = 0, a = 0; a < n; a++)
waste += splitx[a];
/* if we waste more space or use the same amount,
* revert deeper splits and just use larger */
if (waste >= power_of_2_max_i(x)) {
splitx[0] = power_of_2_max_i(x);
memset(splitx + 1, 0, sizeof(int) * (n - 1));
}
else
*nx = newnx;
}
}
static void wm_draw_triple_free(wmDrawTriple *triple)
{
if (triple) {
glDeleteTextures(triple->nx * triple->ny, triple->bind);
glDeleteTextures(1, &triple->bind);
MEM_freeN(triple);
}
}
@@ -434,66 +382,49 @@ static int wm_triple_gen_textures(wmWindow *win, wmDrawTriple *triple)
const int winsize_y = WM_window_pixels_y(win);
GLint maxsize;
int x, y;
/* compute texture sizes */
if (GLEW_ARB_texture_rectangle || GLEW_NV_texture_rectangle || GLEW_EXT_texture_rectangle) {
triple->target = GL_TEXTURE_RECTANGLE_ARB;
triple->nx = 1;
triple->ny = 1;
triple->x[0] = winsize_x;
triple->y[0] = winsize_y;
}
else if (GPU_non_power_of_two_support()) {
triple->target = GL_TEXTURE_2D;
triple->nx = 1;
triple->ny = 1;
triple->x[0] = winsize_x;
triple->y[0] = winsize_y;
}
else {
triple->target = GL_TEXTURE_2D;
triple->nx = 0;
triple->ny = 0;
split_width(winsize_x, MAX_N_TEX, triple->x, &triple->nx);
split_width(winsize_y, MAX_N_TEX, triple->y, &triple->ny);
}
/* generate texture names */
glGenTextures(triple->nx * triple->ny, triple->bind);
triple->x = winsize_x;
triple->y = winsize_y;
if (!triple->bind[0]) {
/* generate texture names */
glGenTextures(1, &triple->bind);
if (!triple->bind) {
/* not the typical failure case but we handle it anyway */
printf("WM: failed to allocate texture for triple buffer drawing (glGenTextures).\n");
return 0;
}
for (y = 0; y < triple->ny; y++) {
for (x = 0; x < triple->nx; x++) {
/* proxy texture is only guaranteed to test for the cases that
* there is only one texture in use, which may not be the case */
maxsize = GPU_max_texture_size();
/* proxy texture is only guaranteed to test for the cases that
* there is only one texture in use, which may not be the case */
maxsize = GPU_max_texture_size();
if (triple->x[x] > maxsize || triple->y[y] > maxsize) {
glBindTexture(triple->target, 0);
printf("WM: failed to allocate texture for triple buffer drawing "
"(texture too large for graphics card).\n");
return 0;
}
if (triple->x > maxsize || triple->y > maxsize) {
glBindTexture(triple->target, 0);
printf("WM: failed to allocate texture for triple buffer drawing "
"(texture too large for graphics card).\n");
return 0;
}
/* setup actual texture */
glBindTexture(triple->target, triple->bind[x + y * triple->nx]);
glTexImage2D(triple->target, 0, GL_RGB8, triple->x[x], triple->y[y], 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(triple->target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(triple->target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glBindTexture(triple->target, 0);
/* setup actual texture */
glBindTexture(triple->target, triple->bind);
glTexImage2D(triple->target, 0, GL_RGB8, triple->x, triple->y, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(triple->target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(triple->target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glBindTexture(triple->target, 0);
/* not sure if this works everywhere .. */
if (glGetError() == GL_OUT_OF_MEMORY) {
printf("WM: failed to allocate texture for triple buffer drawing (out of memory).\n");
return 0;
}
}
/* not sure if this works everywhere .. */
if (glGetError() == GL_OUT_OF_MEMORY) {
printf("WM: failed to allocate texture for triple buffer drawing (out of memory).\n");
return 0;
}
return 1;
@@ -501,72 +432,55 @@ static int wm_triple_gen_textures(wmWindow *win, wmDrawTriple *triple)
void wm_triple_draw_textures(wmWindow *win, wmDrawTriple *triple, float alpha)
{
const int winsize_x = WM_window_pixels_x(win);
const int winsize_y = WM_window_pixels_y(win);
const int sizex = WM_window_pixels_x(win);
const int sizey = WM_window_pixels_y(win);
float halfx, halfy, ratiox, ratioy;
int x, y, sizex, sizey, offx, offy;
glEnable(triple->target);
for (y = 0, offy = 0; y < triple->ny; offy += triple->y[y], y++) {
for (x = 0, offx = 0; x < triple->nx; offx += triple->x[x], x++) {
sizex = (x == triple->nx - 1) ? winsize_x - offx : triple->x[x];
sizey = (y == triple->ny - 1) ? winsize_y - offy : triple->y[y];
/* wmOrtho for the screen has this same offset */
ratiox = sizex;
ratioy = sizey;
halfx = GLA_PIXEL_OFS;
halfy = GLA_PIXEL_OFS;
/* wmOrtho for the screen has this same offset */
ratiox = sizex;
ratioy = sizey;
halfx = GLA_PIXEL_OFS;
halfy = GLA_PIXEL_OFS;
/* texture rectangle has unnormalized coordinates */
if (triple->target == GL_TEXTURE_2D) {
ratiox /= triple->x[x];
ratioy /= triple->y[y];
halfx /= triple->x[x];
halfy /= triple->y[y];
}
glBindTexture(triple->target, triple->bind[x + y * triple->nx]);
glColor4f(1.0f, 1.0f, 1.0f, alpha);
glBegin(GL_QUADS);
glTexCoord2f(halfx, halfy);
glVertex2f(offx, offy);
glTexCoord2f(ratiox + halfx, halfy);
glVertex2f(offx + sizex, offy);
glTexCoord2f(ratiox + halfx, ratioy + halfy);
glVertex2f(offx + sizex, offy + sizey);
glTexCoord2f(halfx, ratioy + halfy);
glVertex2f(offx, offy + sizey);
glEnd();
}
/* texture rectangle has unnormalized coordinates */
if (triple->target == GL_TEXTURE_2D) {
ratiox /= triple->x;
ratioy /= triple->y;
halfx /= triple->x;
halfy /= triple->y;
}
glBindTexture(triple->target, triple->bind);
glColor4f(1.0f, 1.0f, 1.0f, alpha);
glBegin(GL_QUADS);
glTexCoord2f(halfx, halfy);
glVertex2f(0, 0);
glTexCoord2f(ratiox + halfx, halfy);
glVertex2f(sizex, 0);
glTexCoord2f(ratiox + halfx, ratioy + halfy);
glVertex2f(sizex, sizey);
glTexCoord2f(halfx, ratioy + halfy);
glVertex2f(0, sizey);
glEnd();
glBindTexture(triple->target, 0);
glDisable(triple->target);
}
static void wm_triple_copy_textures(wmWindow *win, wmDrawTriple *triple)
{
const int winsize_x = WM_window_pixels_x(win);
const int winsize_y = WM_window_pixels_y(win);
const int sizex = WM_window_pixels_x(win);
const int sizey = WM_window_pixels_y(win);
int x, y, sizex, sizey, offx, offy;
for (y = 0, offy = 0; y < triple->ny; offy += triple->y[y], y++) {
for (x = 0, offx = 0; x < triple->nx; offx += triple->x[x], x++) {
sizex = (x == triple->nx - 1) ? winsize_x - offx : triple->x[x];
sizey = (y == triple->ny - 1) ? winsize_y - offy : triple->y[y];
glBindTexture(triple->target, triple->bind[x + y * triple->nx]);
glCopyTexSubImage2D(triple->target, 0, 0, 0, offx, offy, sizex, sizey);
}
}
glBindTexture(triple->target, triple->bind);
glCopyTexSubImage2D(triple->target, 0, 0, 0, 0, 0, sizex, sizey);
glBindTexture(triple->target, 0);
}

View File

@@ -195,7 +195,6 @@ static void wm_method_draw_stereo3d_sidebyside(wmWindow *win)
wmDrawData *drawdata;
wmDrawTriple *triple;
float halfx, halfy, ratiox, ratioy;
int x, y, offx, offy;
float alpha = 1.0f;
int view;
int soffx;
@@ -217,44 +216,40 @@ static void wm_method_draw_stereo3d_sidebyside(wmWindow *win)
glEnable(triple->target);
for (y = 0, offy = 0; y < triple->ny; offy += triple->y[y], y++) {
for (x = 0, offx = 0; x < triple->nx; offx += triple->x[x], x++) {
const int sizex = triple->x[x];
const int sizey = triple->y[y];
const int sizex = triple->x;
const int sizey = triple->y;
/* wmOrtho for the screen has this same offset */
ratiox = sizex;
ratioy = sizey;
halfx = GLA_PIXEL_OFS;
halfy = GLA_PIXEL_OFS;
/* wmOrtho for the screen has this same offset */
ratiox = sizex;
ratioy = sizey;
halfx = GLA_PIXEL_OFS;
halfy = GLA_PIXEL_OFS;
/* texture rectangle has unnormalized coordinates */
if (triple->target == GL_TEXTURE_2D) {
ratiox /= triple->x[x];
ratioy /= triple->y[y];
halfx /= triple->x[x];
halfy /= triple->y[y];
}
glBindTexture(triple->target, triple->bind[x + y * triple->nx]);
glColor4f(1.0f, 1.0f, 1.0f, alpha);
glBegin(GL_QUADS);
glTexCoord2f(halfx, halfy);
glVertex2f(soffx + (offx * 0.5f), offy);
glTexCoord2f(ratiox + halfx, halfy);
glVertex2f(soffx + ((offx + sizex) * 0.5f), offy);
glTexCoord2f(ratiox + halfx, ratioy + halfy);
glVertex2f(soffx + ((offx + sizex) * 0.5f), offy + sizey);
glTexCoord2f(halfx, ratioy + halfy);
glVertex2f(soffx + (offx * 0.5f), offy + sizey);
glEnd();
}
/* texture rectangle has unnormalized coordinates */
if (triple->target == GL_TEXTURE_2D) {
ratiox /= triple->x;
ratioy /= triple->y;
halfx /= triple->x;
halfy /= triple->y;
}
glBindTexture(triple->target, triple->bind);
glColor4f(1.0f, 1.0f, 1.0f, alpha);
glBegin(GL_QUADS);
glTexCoord2f(halfx, halfy);
glVertex2f(soffx, 0);
glTexCoord2f(ratiox + halfx, halfy);
glVertex2f(soffx + (sizex * 0.5f), 0);
glTexCoord2f(ratiox + halfx, ratioy + halfy);
glVertex2f(soffx + (sizex * 0.5f), sizey);
glTexCoord2f(halfx, ratioy + halfy);
glVertex2f(soffx, sizey);
glEnd();
glBindTexture(triple->target, 0);
glDisable(triple->target);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
@@ -266,7 +261,6 @@ static void wm_method_draw_stereo3d_topbottom(wmWindow *win)
wmDrawData *drawdata;
wmDrawTriple *triple;
float halfx, halfy, ratiox, ratioy;
int x, y, offx, offy;
float alpha = 1.0f;
int view;
int soffy;
@@ -284,44 +278,40 @@ static void wm_method_draw_stereo3d_topbottom(wmWindow *win)
glEnable(triple->target);
for (y = 0, offy = 0; y < triple->ny; offy += triple->y[y], y++) {
for (x = 0, offx = 0; x < triple->nx; offx += triple->x[x], x++) {
const int sizex = triple->x[x];
const int sizey = triple->y[y];
const int sizex = triple->x;
const int sizey = triple->y;
/* wmOrtho for the screen has this same offset */
ratiox = sizex;
ratioy = sizey;
halfx = GLA_PIXEL_OFS;
halfy = GLA_PIXEL_OFS;
/* wmOrtho for the screen has this same offset */
ratiox = sizex;
ratioy = sizey;
halfx = GLA_PIXEL_OFS;
halfy = GLA_PIXEL_OFS;
/* texture rectangle has unnormalized coordinates */
if (triple->target == GL_TEXTURE_2D) {
ratiox /= triple->x[x];
ratioy /= triple->y[y];
halfx /= triple->x[x];
halfy /= triple->y[y];
}
glBindTexture(triple->target, triple->bind[x + y * triple->nx]);
glColor4f(1.0f, 1.0f, 1.0f, alpha);
glBegin(GL_QUADS);
glTexCoord2f(halfx, halfy);
glVertex2f(offx, soffy + (offy * 0.5f));
glTexCoord2f(ratiox + halfx, halfy);
glVertex2f(offx + sizex, soffy + (offy * 0.5f));
glTexCoord2f(ratiox + halfx, ratioy + halfy);
glVertex2f(offx + sizex, soffy + ((offy + sizey) * 0.5f));
glTexCoord2f(halfx, ratioy + halfy);
glVertex2f(offx, soffy + ((offy + sizey) * 0.5f));
glEnd();
}
/* texture rectangle has unnormalized coordinates */
if (triple->target == GL_TEXTURE_2D) {
ratiox /= triple->x;
ratioy /= triple->y;
halfx /= triple->x;
halfy /= triple->y;
}
glBindTexture(triple->target, triple->bind);
glColor4f(1.0f, 1.0f, 1.0f, alpha);
glBegin(GL_QUADS);
glTexCoord2f(halfx, halfy);
glVertex2f(0, soffy);
glTexCoord2f(ratiox + halfx, halfy);
glVertex2f(sizex, soffy);
glTexCoord2f(ratiox + halfx, ratioy + halfy);
glVertex2f(sizex, soffy + (sizey * 0.5f));
glTexCoord2f(halfx, ratioy + halfy);
glVertex2f(0, soffy + (sizey * 0.5f));
glEnd();
glBindTexture(triple->target, 0);
glDisable(triple->target);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);

View File

@@ -34,13 +34,9 @@
#include "GPU_glew.h"
#define MAX_N_TEX 3
typedef struct wmDrawTriple {
GLuint bind[MAX_N_TEX * MAX_N_TEX];
int x[MAX_N_TEX], y[MAX_N_TEX];
int nx, ny;
GLuint bind;
int x, y;
GLenum target;
} wmDrawTriple;

View File

@@ -195,7 +195,7 @@ bool BL_Texture::InitFromImage(int unit, Image *img, bool mipmap)
void BL_Texture::InitGLTex(unsigned int *pix,int x,int y,bool mipmap)
{
if (!GPU_non_power_of_two_support() && (!is_power_of_2_i(x) || !is_power_of_2_i(y)) ) {
if (!GPU_full_non_power_of_two_support() && (!is_power_of_2_i(x) || !is_power_of_2_i(y)) ) {
InitNonPow2Tex(pix, x,y,mipmap);
return;
}

View File

@@ -1680,6 +1680,6 @@ void RAS_OpenGLRasterizer::PrintHardwareInfo()
pprint(" GL_ARB_texture_env_combine supported? "<< (GLEW_ARB_texture_env_combine?"yes.":"no."));
pprint(" GL_ARB_texture_non_power_of_two supported " << (GPU_non_power_of_two_support()?"yes.":"no."));
pprint(" GL_ARB_texture_non_power_of_two supported " << (GPU_full_non_power_of_two_support()?"yes.":"no."));
}