How to properly upscale a texture in opengl?

Multi tool use
Let's say, for the simplicity of this question, I want to create a texture containing a color gradient from black to red. I know there are much easier ways to achieve this but it is a good example for my problem.
I figured, i could simply create a texture from an float array like so:
float values[4] {
0.f, 1.f,
0.f, 1.f
}
// gen texture
unsigned int texId;
glGenTextures(1, &texId);
glBindTexture(GL_TEXTURE_2D, texId);
// set filter and wrap
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// copy values
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, 2, 2, 0, GL_RED, GL_FLOAT, values);
And draw it:
float vertices[8] {
-1.f, -1.f, 0.f, 0.f,
1.f, -1.f, 1.f, 0.f,
1.f, 1.f, 1.f, 1.f,
-1.f, 1.f, 0.f, 1.f
}
// generate vertex buffer, vertex buffer layout and vertex array
unsigned int[6] indices {
0, 1, 2,
2, 3, 1
}
// generate index buffer
// bind everything
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
Where the bound vertex shader looks like this:
#version 330 core
layout(location=0) in vec2 in_position;
layout(location=1) in vec2 in_texCoords;
out vec2 texCoords;
void main() {
gl_Position = vec4(in_position, 0.f, 1.f);
texCoords = in_texCoords;
}
And the fragment shader like this:
#version 330 core
layout(location = 0) out vec4 out_color;
in vec2 texCoords;
uniform sampler2D u_gradient;
void main() {
float red = texture(u_gradient, texCoords).r;
out_color = vec4(red, 0.f, 0.f, 1.f);
}
Following this I'd expect to get an color gradient from left to right (black to red) across my entire window.
However what I get is a gradient from about 1/4 to 3/4 of the window in x and y direction (See image below). I've also noted that the wrap of repeat does not seem to apply here as what I get looks like mirror-repeat.
Result:
I've played around with the fragment shader using fixed values instead of texCoords and figured that a range from .25 to .75 on the x axis represents the entire gradient (.25 maps to 0 for red and .75 to 1).
Changing the amount of 'steps' passed as values to the texture (eg. a 4x4 array) did not change the results.
I've also tried using an image as texture (loaded with stb_image, resolution 1920x1080) which works perfectly fine and spreads across the entire screen.
For clarification: Why do the texCoords for the gradient range from .25 to .75 and not from 0 to 1 and how can I fix it (besides adjusting the texCoords itself)?
c++ opengl glsl textures
add a comment |
Let's say, for the simplicity of this question, I want to create a texture containing a color gradient from black to red. I know there are much easier ways to achieve this but it is a good example for my problem.
I figured, i could simply create a texture from an float array like so:
float values[4] {
0.f, 1.f,
0.f, 1.f
}
// gen texture
unsigned int texId;
glGenTextures(1, &texId);
glBindTexture(GL_TEXTURE_2D, texId);
// set filter and wrap
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// copy values
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, 2, 2, 0, GL_RED, GL_FLOAT, values);
And draw it:
float vertices[8] {
-1.f, -1.f, 0.f, 0.f,
1.f, -1.f, 1.f, 0.f,
1.f, 1.f, 1.f, 1.f,
-1.f, 1.f, 0.f, 1.f
}
// generate vertex buffer, vertex buffer layout and vertex array
unsigned int[6] indices {
0, 1, 2,
2, 3, 1
}
// generate index buffer
// bind everything
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
Where the bound vertex shader looks like this:
#version 330 core
layout(location=0) in vec2 in_position;
layout(location=1) in vec2 in_texCoords;
out vec2 texCoords;
void main() {
gl_Position = vec4(in_position, 0.f, 1.f);
texCoords = in_texCoords;
}
And the fragment shader like this:
#version 330 core
layout(location = 0) out vec4 out_color;
in vec2 texCoords;
uniform sampler2D u_gradient;
void main() {
float red = texture(u_gradient, texCoords).r;
out_color = vec4(red, 0.f, 0.f, 1.f);
}
Following this I'd expect to get an color gradient from left to right (black to red) across my entire window.
However what I get is a gradient from about 1/4 to 3/4 of the window in x and y direction (See image below). I've also noted that the wrap of repeat does not seem to apply here as what I get looks like mirror-repeat.
Result:
I've played around with the fragment shader using fixed values instead of texCoords and figured that a range from .25 to .75 on the x axis represents the entire gradient (.25 maps to 0 for red and .75 to 1).
Changing the amount of 'steps' passed as values to the texture (eg. a 4x4 array) did not change the results.
I've also tried using an image as texture (loaded with stb_image, resolution 1920x1080) which works perfectly fine and spreads across the entire screen.
For clarification: Why do the texCoords for the gradient range from .25 to .75 and not from 0 to 1 and how can I fix it (besides adjusting the texCoords itself)?
c++ opengl glsl textures
Please, have a look at Textures objects and parameters, specifically concerning the effect ofGL_REPEAT
. TryGL_CLAMP_TO_EDGE
instead. (Btw. you have set twiceGL_TEXTURE_WRAP_S
- the 2nd probably was intended to beGL_TEXTURE_WRAP_T
.)
– Scheff
Dec 30 '18 at 7:13
The wrap mistake happend while copy and pasting the code. It was right in my code and I also fixed it here. @Scheff
– Kanjiu
Dec 30 '18 at 14:24
add a comment |
Let's say, for the simplicity of this question, I want to create a texture containing a color gradient from black to red. I know there are much easier ways to achieve this but it is a good example for my problem.
I figured, i could simply create a texture from an float array like so:
float values[4] {
0.f, 1.f,
0.f, 1.f
}
// gen texture
unsigned int texId;
glGenTextures(1, &texId);
glBindTexture(GL_TEXTURE_2D, texId);
// set filter and wrap
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// copy values
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, 2, 2, 0, GL_RED, GL_FLOAT, values);
And draw it:
float vertices[8] {
-1.f, -1.f, 0.f, 0.f,
1.f, -1.f, 1.f, 0.f,
1.f, 1.f, 1.f, 1.f,
-1.f, 1.f, 0.f, 1.f
}
// generate vertex buffer, vertex buffer layout and vertex array
unsigned int[6] indices {
0, 1, 2,
2, 3, 1
}
// generate index buffer
// bind everything
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
Where the bound vertex shader looks like this:
#version 330 core
layout(location=0) in vec2 in_position;
layout(location=1) in vec2 in_texCoords;
out vec2 texCoords;
void main() {
gl_Position = vec4(in_position, 0.f, 1.f);
texCoords = in_texCoords;
}
And the fragment shader like this:
#version 330 core
layout(location = 0) out vec4 out_color;
in vec2 texCoords;
uniform sampler2D u_gradient;
void main() {
float red = texture(u_gradient, texCoords).r;
out_color = vec4(red, 0.f, 0.f, 1.f);
}
Following this I'd expect to get an color gradient from left to right (black to red) across my entire window.
However what I get is a gradient from about 1/4 to 3/4 of the window in x and y direction (See image below). I've also noted that the wrap of repeat does not seem to apply here as what I get looks like mirror-repeat.
Result:
I've played around with the fragment shader using fixed values instead of texCoords and figured that a range from .25 to .75 on the x axis represents the entire gradient (.25 maps to 0 for red and .75 to 1).
Changing the amount of 'steps' passed as values to the texture (eg. a 4x4 array) did not change the results.
I've also tried using an image as texture (loaded with stb_image, resolution 1920x1080) which works perfectly fine and spreads across the entire screen.
For clarification: Why do the texCoords for the gradient range from .25 to .75 and not from 0 to 1 and how can I fix it (besides adjusting the texCoords itself)?
c++ opengl glsl textures
Let's say, for the simplicity of this question, I want to create a texture containing a color gradient from black to red. I know there are much easier ways to achieve this but it is a good example for my problem.
I figured, i could simply create a texture from an float array like so:
float values[4] {
0.f, 1.f,
0.f, 1.f
}
// gen texture
unsigned int texId;
glGenTextures(1, &texId);
glBindTexture(GL_TEXTURE_2D, texId);
// set filter and wrap
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// copy values
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, 2, 2, 0, GL_RED, GL_FLOAT, values);
And draw it:
float vertices[8] {
-1.f, -1.f, 0.f, 0.f,
1.f, -1.f, 1.f, 0.f,
1.f, 1.f, 1.f, 1.f,
-1.f, 1.f, 0.f, 1.f
}
// generate vertex buffer, vertex buffer layout and vertex array
unsigned int[6] indices {
0, 1, 2,
2, 3, 1
}
// generate index buffer
// bind everything
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
Where the bound vertex shader looks like this:
#version 330 core
layout(location=0) in vec2 in_position;
layout(location=1) in vec2 in_texCoords;
out vec2 texCoords;
void main() {
gl_Position = vec4(in_position, 0.f, 1.f);
texCoords = in_texCoords;
}
And the fragment shader like this:
#version 330 core
layout(location = 0) out vec4 out_color;
in vec2 texCoords;
uniform sampler2D u_gradient;
void main() {
float red = texture(u_gradient, texCoords).r;
out_color = vec4(red, 0.f, 0.f, 1.f);
}
Following this I'd expect to get an color gradient from left to right (black to red) across my entire window.
However what I get is a gradient from about 1/4 to 3/4 of the window in x and y direction (See image below). I've also noted that the wrap of repeat does not seem to apply here as what I get looks like mirror-repeat.
Result:
I've played around with the fragment shader using fixed values instead of texCoords and figured that a range from .25 to .75 on the x axis represents the entire gradient (.25 maps to 0 for red and .75 to 1).
Changing the amount of 'steps' passed as values to the texture (eg. a 4x4 array) did not change the results.
I've also tried using an image as texture (loaded with stb_image, resolution 1920x1080) which works perfectly fine and spreads across the entire screen.
For clarification: Why do the texCoords for the gradient range from .25 to .75 and not from 0 to 1 and how can I fix it (besides adjusting the texCoords itself)?
c++ opengl glsl textures
c++ opengl glsl textures
edited Jan 12 at 12:12


Rabbid76
35.8k113247
35.8k113247
asked Dec 30 '18 at 0:15


KanjiuKanjiu
41110
41110
Please, have a look at Textures objects and parameters, specifically concerning the effect ofGL_REPEAT
. TryGL_CLAMP_TO_EDGE
instead. (Btw. you have set twiceGL_TEXTURE_WRAP_S
- the 2nd probably was intended to beGL_TEXTURE_WRAP_T
.)
– Scheff
Dec 30 '18 at 7:13
The wrap mistake happend while copy and pasting the code. It was right in my code and I also fixed it here. @Scheff
– Kanjiu
Dec 30 '18 at 14:24
add a comment |
Please, have a look at Textures objects and parameters, specifically concerning the effect ofGL_REPEAT
. TryGL_CLAMP_TO_EDGE
instead. (Btw. you have set twiceGL_TEXTURE_WRAP_S
- the 2nd probably was intended to beGL_TEXTURE_WRAP_T
.)
– Scheff
Dec 30 '18 at 7:13
The wrap mistake happend while copy and pasting the code. It was right in my code and I also fixed it here. @Scheff
– Kanjiu
Dec 30 '18 at 14:24
Please, have a look at Textures objects and parameters, specifically concerning the effect of
GL_REPEAT
. Try GL_CLAMP_TO_EDGE
instead. (Btw. you have set twice GL_TEXTURE_WRAP_S
- the 2nd probably was intended to be GL_TEXTURE_WRAP_T
.)– Scheff
Dec 30 '18 at 7:13
Please, have a look at Textures objects and parameters, specifically concerning the effect of
GL_REPEAT
. Try GL_CLAMP_TO_EDGE
instead. (Btw. you have set twice GL_TEXTURE_WRAP_S
- the 2nd probably was intended to be GL_TEXTURE_WRAP_T
.)– Scheff
Dec 30 '18 at 7:13
The wrap mistake happend while copy and pasting the code. It was right in my code and I also fixed it here. @Scheff
– Kanjiu
Dec 30 '18 at 14:24
The wrap mistake happend while copy and pasting the code. It was right in my code and I also fixed it here. @Scheff
– Kanjiu
Dec 30 '18 at 14:24
add a comment |
1 Answer
1
active
oldest
votes
Lets assume you have a 2x2 texture
2x2 Texture
If this texture is wrapped on a grid of 6x6 fragments, the the center of a texel is on exactly on the texel in the middel of 3x3 tile of the 6x6 square:
6x6 quad
The color of the other fragments depends on the the texture parameters - see glTexParameter
.
Since the texture is magnified, the GL_TEXTURE_MAG_FILTER
is significant.
If it is GL_NEAREST
, then the color of the fragments is that one of the closest texel, to the texture coordinates of the fragment:
If it is GL_LINEAR
, then the color is interpolated, by the weighted average of the 4 pixels which are closest to the texture coordinates.
The interpolation at the borders of the 6x6 quad depends on the wrap parameters GL_TEXTURE_WRAP_S
and GL_TEXTURE_WRAP_T
.
If the parameters are GL_REPEAT
(which is default), the the texture is treated as an endless texture and the interpolation of the interpolation of the color at the borders takes into account the texels on the opposite side of the texture. This is used for seamless textures and tiling:
If it is GL_CLAMP_TO_EDGE
, then the interpolated color at the borders is clamped to the color of the texels at the border of the texture:
Apply the texture wrap parameter GL_CLAMP_TO_EDGE
to the texture object,
float values[4] { 0.f, 1.f, 0.f, 1.f };
unsigned int texId;
glGenTextures(1, &texId);
glBindTexture(GL_TEXTURE_2D, texId);
// set filter and wrap
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// copy values
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, 2, 2, 0, GL_RED, GL_FLOAT, values);
to get the following gradient:
2
It doesn't become clear from your answer right now, so I think you should maybe add some clarification that texel values are defined for the center of each "cell" in the texel grid, and the coordinates 0 and 1 are not in texel centers. Maybe also add a modification to OPs original code to address texel centers properly and show the results.
– datenwolf
Dec 30 '18 at 10:10
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53974343%2fhow-to-properly-upscale-a-texture-in-opengl%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Lets assume you have a 2x2 texture
2x2 Texture
If this texture is wrapped on a grid of 6x6 fragments, the the center of a texel is on exactly on the texel in the middel of 3x3 tile of the 6x6 square:
6x6 quad
The color of the other fragments depends on the the texture parameters - see glTexParameter
.
Since the texture is magnified, the GL_TEXTURE_MAG_FILTER
is significant.
If it is GL_NEAREST
, then the color of the fragments is that one of the closest texel, to the texture coordinates of the fragment:
If it is GL_LINEAR
, then the color is interpolated, by the weighted average of the 4 pixels which are closest to the texture coordinates.
The interpolation at the borders of the 6x6 quad depends on the wrap parameters GL_TEXTURE_WRAP_S
and GL_TEXTURE_WRAP_T
.
If the parameters are GL_REPEAT
(which is default), the the texture is treated as an endless texture and the interpolation of the interpolation of the color at the borders takes into account the texels on the opposite side of the texture. This is used for seamless textures and tiling:
If it is GL_CLAMP_TO_EDGE
, then the interpolated color at the borders is clamped to the color of the texels at the border of the texture:
Apply the texture wrap parameter GL_CLAMP_TO_EDGE
to the texture object,
float values[4] { 0.f, 1.f, 0.f, 1.f };
unsigned int texId;
glGenTextures(1, &texId);
glBindTexture(GL_TEXTURE_2D, texId);
// set filter and wrap
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// copy values
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, 2, 2, 0, GL_RED, GL_FLOAT, values);
to get the following gradient:
2
It doesn't become clear from your answer right now, so I think you should maybe add some clarification that texel values are defined for the center of each "cell" in the texel grid, and the coordinates 0 and 1 are not in texel centers. Maybe also add a modification to OPs original code to address texel centers properly and show the results.
– datenwolf
Dec 30 '18 at 10:10
add a comment |
Lets assume you have a 2x2 texture
2x2 Texture
If this texture is wrapped on a grid of 6x6 fragments, the the center of a texel is on exactly on the texel in the middel of 3x3 tile of the 6x6 square:
6x6 quad
The color of the other fragments depends on the the texture parameters - see glTexParameter
.
Since the texture is magnified, the GL_TEXTURE_MAG_FILTER
is significant.
If it is GL_NEAREST
, then the color of the fragments is that one of the closest texel, to the texture coordinates of the fragment:
If it is GL_LINEAR
, then the color is interpolated, by the weighted average of the 4 pixels which are closest to the texture coordinates.
The interpolation at the borders of the 6x6 quad depends on the wrap parameters GL_TEXTURE_WRAP_S
and GL_TEXTURE_WRAP_T
.
If the parameters are GL_REPEAT
(which is default), the the texture is treated as an endless texture and the interpolation of the interpolation of the color at the borders takes into account the texels on the opposite side of the texture. This is used for seamless textures and tiling:
If it is GL_CLAMP_TO_EDGE
, then the interpolated color at the borders is clamped to the color of the texels at the border of the texture:
Apply the texture wrap parameter GL_CLAMP_TO_EDGE
to the texture object,
float values[4] { 0.f, 1.f, 0.f, 1.f };
unsigned int texId;
glGenTextures(1, &texId);
glBindTexture(GL_TEXTURE_2D, texId);
// set filter and wrap
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// copy values
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, 2, 2, 0, GL_RED, GL_FLOAT, values);
to get the following gradient:
2
It doesn't become clear from your answer right now, so I think you should maybe add some clarification that texel values are defined for the center of each "cell" in the texel grid, and the coordinates 0 and 1 are not in texel centers. Maybe also add a modification to OPs original code to address texel centers properly and show the results.
– datenwolf
Dec 30 '18 at 10:10
add a comment |
Lets assume you have a 2x2 texture
2x2 Texture
If this texture is wrapped on a grid of 6x6 fragments, the the center of a texel is on exactly on the texel in the middel of 3x3 tile of the 6x6 square:
6x6 quad
The color of the other fragments depends on the the texture parameters - see glTexParameter
.
Since the texture is magnified, the GL_TEXTURE_MAG_FILTER
is significant.
If it is GL_NEAREST
, then the color of the fragments is that one of the closest texel, to the texture coordinates of the fragment:
If it is GL_LINEAR
, then the color is interpolated, by the weighted average of the 4 pixels which are closest to the texture coordinates.
The interpolation at the borders of the 6x6 quad depends on the wrap parameters GL_TEXTURE_WRAP_S
and GL_TEXTURE_WRAP_T
.
If the parameters are GL_REPEAT
(which is default), the the texture is treated as an endless texture and the interpolation of the interpolation of the color at the borders takes into account the texels on the opposite side of the texture. This is used for seamless textures and tiling:
If it is GL_CLAMP_TO_EDGE
, then the interpolated color at the borders is clamped to the color of the texels at the border of the texture:
Apply the texture wrap parameter GL_CLAMP_TO_EDGE
to the texture object,
float values[4] { 0.f, 1.f, 0.f, 1.f };
unsigned int texId;
glGenTextures(1, &texId);
glBindTexture(GL_TEXTURE_2D, texId);
// set filter and wrap
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// copy values
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, 2, 2, 0, GL_RED, GL_FLOAT, values);
to get the following gradient:
Lets assume you have a 2x2 texture
2x2 Texture
If this texture is wrapped on a grid of 6x6 fragments, the the center of a texel is on exactly on the texel in the middel of 3x3 tile of the 6x6 square:
6x6 quad
The color of the other fragments depends on the the texture parameters - see glTexParameter
.
Since the texture is magnified, the GL_TEXTURE_MAG_FILTER
is significant.
If it is GL_NEAREST
, then the color of the fragments is that one of the closest texel, to the texture coordinates of the fragment:
If it is GL_LINEAR
, then the color is interpolated, by the weighted average of the 4 pixels which are closest to the texture coordinates.
The interpolation at the borders of the 6x6 quad depends on the wrap parameters GL_TEXTURE_WRAP_S
and GL_TEXTURE_WRAP_T
.
If the parameters are GL_REPEAT
(which is default), the the texture is treated as an endless texture and the interpolation of the interpolation of the color at the borders takes into account the texels on the opposite side of the texture. This is used for seamless textures and tiling:
If it is GL_CLAMP_TO_EDGE
, then the interpolated color at the borders is clamped to the color of the texels at the border of the texture:
Apply the texture wrap parameter GL_CLAMP_TO_EDGE
to the texture object,
float values[4] { 0.f, 1.f, 0.f, 1.f };
unsigned int texId;
glGenTextures(1, &texId);
glBindTexture(GL_TEXTURE_2D, texId);
// set filter and wrap
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// copy values
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, 2, 2, 0, GL_RED, GL_FLOAT, values);
to get the following gradient:
edited Dec 30 '18 at 12:26
answered Dec 30 '18 at 8:59


Rabbid76Rabbid76
35.8k113247
35.8k113247
2
It doesn't become clear from your answer right now, so I think you should maybe add some clarification that texel values are defined for the center of each "cell" in the texel grid, and the coordinates 0 and 1 are not in texel centers. Maybe also add a modification to OPs original code to address texel centers properly and show the results.
– datenwolf
Dec 30 '18 at 10:10
add a comment |
2
It doesn't become clear from your answer right now, so I think you should maybe add some clarification that texel values are defined for the center of each "cell" in the texel grid, and the coordinates 0 and 1 are not in texel centers. Maybe also add a modification to OPs original code to address texel centers properly and show the results.
– datenwolf
Dec 30 '18 at 10:10
2
2
It doesn't become clear from your answer right now, so I think you should maybe add some clarification that texel values are defined for the center of each "cell" in the texel grid, and the coordinates 0 and 1 are not in texel centers. Maybe also add a modification to OPs original code to address texel centers properly and show the results.
– datenwolf
Dec 30 '18 at 10:10
It doesn't become clear from your answer right now, so I think you should maybe add some clarification that texel values are defined for the center of each "cell" in the texel grid, and the coordinates 0 and 1 are not in texel centers. Maybe also add a modification to OPs original code to address texel centers properly and show the results.
– datenwolf
Dec 30 '18 at 10:10
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53974343%2fhow-to-properly-upscale-a-texture-in-opengl%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
izP,DKEMdo56hqaA15zIU8,SWEM8OVrS1OUmRqYM52,LeTS6QXRjLnF7pC,878GDlAo8GCXGSaGnOcH,VXFXXMuP1J,j8,thfJc2H
Please, have a look at Textures objects and parameters, specifically concerning the effect of
GL_REPEAT
. TryGL_CLAMP_TO_EDGE
instead. (Btw. you have set twiceGL_TEXTURE_WRAP_S
- the 2nd probably was intended to beGL_TEXTURE_WRAP_T
.)– Scheff
Dec 30 '18 at 7:13
The wrap mistake happend while copy and pasting the code. It was right in my code and I also fixed it here. @Scheff
– Kanjiu
Dec 30 '18 at 14:24