Entalpi
Entalpi

Reputation: 2033

Sample from GL_TEXTURE_1D in fragment shader

Been trying to sample from a 1D texture (.png), got a model with the correct texture coordinates and all but I just can't get the texture to show up. The geometry is rendering just black, there must be something I have missunderstood about textures in OpenGL but can't see it.

Any pointers?

C++

// Setup
GLint texCoordAttrib = glGetAttribLocation(batch_shader_program, "vTexCoord");
glVertexAttribPointer(texCoordAttrib, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex<float>), (const void *)offsetof(Vertex<float>, texCoord));
glEnableVertexAttribArray(texCoordAttrib);

// Loading
GLuint load_1d_texture(std::string filepath) {
  SDL_Surface *image = IMG_Load(filepath.c_str());
  int width  = image->w;
  GLuint texture;
  glGenTextures(1, &texture);
  glBindTexture(GL_TEXTURE_1D, texture);
  glTexImage2D(GL_TEXTURE_1D, 0, GL_RGBA, width, 0, GL_RGBA, GL_UNSIGNED_BYTE, image->pixels);
  SDL_FreeSurface(image);
  return texture;
}

// Rendering
glUseProgram(batch.gl_program);
glBindTexture(GL_TEXTURE_1D, batch.mesh.texture.gl_texture_reference);
glDraw***

Vertex Shader

#version 330 core

in vec3 position;
in vec4 vColor;
in vec3 normal; // Polygon normal
in vec2 vTexCoord;

// Model
in mat4 model;

out vec4 fColor; 
out vec3 fTexcoord;

// View or a.k.a camera matrix
uniform mat4 camera_view;

// Projection or a.k.a perspective matrix
uniform mat4 projection;

void main() {
   gl_Position = projection * camera_view * model * vec4(position, 1.0);
   fTexcoord = vec3(vTexCoord, 1.0);
}

Fragment Shader

#version 330 core   

in  vec4 fColor; 
out vec4 outColor;

in vec3 fTexcoord;   // passthrough shading for interpolated textures
uniform sampler1D sampler;

void main() {
   outColor = texture(sampler, fTexcoord.x);
}

Upvotes: 0

Views: 468

Answers (2)

Entalpi
Entalpi

Reputation: 2033

In the end there was no problem, only a bug in the texture coordinate loading (it took the wrong indices from the vertices..)..

Upvotes: 0

Nicol Bolas
Nicol Bolas

Reputation: 473192

glBindTexture(GL_TEXTURE_2D, texture);

glBindTexture(GL_TEXTURE_1D, batch.mesh.texture.gl_texture_reference);

Assuming that these two lines of code are talking about the same OpenGL object, you cannot do that. A texture that uses the 2D texture target is a 2D texture. It is not a 1D texture, nor is it a 2D array texture with one layer or a 3D texture with depth 1. It is a 2D texture.

Once you bind a texture object after generating it, the texture's target is fixed. You can use view textures to create a view of the same storage with different targets, but the original texture object itself is unaffected by this. And you can't create a 1D view of a 2D texture.

You should have gotten a GL_INVALID_OPERATION error when you tried to bind the 2D texture as if it were 1D. You should always check for errors when you run into OpenGL problems.

Upvotes: 1

Related Questions