How to use either color or texture in glsl?

#1
  • I’m starting use modern opengl for my game(GLSL). But it’s sound like a bit of crazy to me.
  • What if I want to draw vertices with colors only?
  • What if I want to draw image by texture only?
    It maybe solve by use uniform in glsl:
    in vec2 texCoord;

    uniform vec4 uColor;
    uniform sampler2D uTexture;

    void main(){
        gl_FragColor = texture2D(uTexture, texCoord) + uColor;
    }
  • But I want specific color per vertex. and why I have to take either texture or color while I’m just use only one?
  • Yes, you can swith between glsl programs by glUseProgram, but create program, compile, link, switch is not the zero cost.
    So is there any other solution for this? This is just only small piece of the code, so how glsl can be flexible if it has issue like this? I really don’t understand.
#2

Use a solid white texture (a 1x1 texture is fine).

Set the colour to white.

It’s more common to multiply the texture with the colour. The most common use of a texture is as a diffuse reflection map, indicating the proportion of incoming light which is reflected. If you’re adding them, use black (rather than white) to leave the colour unchanged.

You don’t have to re-create the program object each time. You just need to call glUseProgram to select the program. But for something this simple, you may as well use one program and just change the uniforms.

#3
  • Thanks for the answer.
  • Well, it’s not really what I want to do, I known I can use glUseProgram in a loop.
  • Problem is I will use either colors or texture, each texture is has corresponding color, so this solution cannot solve, right?
#4
  • By the way, how can I format the segment as the code and not the regular text? Thanks!
#6

Just surround the code block with ``` tags (placed on their own lines).

#7

To further your question, please explain why the solution that @GClements provided is insufficient for you:

#8
  • For example, if you want a vertices has individual color, so you can do something like this:
  • Vertex shader:
attribute vec3 aPos;
attribute vec3 aColor;
attribute vec2 aTexCoord;

varying vec3 fsColor;
varying vec2 fsTexCoord;

void main(){
    fsColor = aColor;
    fsTexCoord = aTexCoord;
    gl_Position = vec4(aPos, 1.0);
}

and then in the fragment shader:


varying vec3 fsColor;
varying vec2 fsTexCoord;

uniform sampler2D uTexture;

void main(){
    gl_FragColor = texture2D(uTexture, fsTexCoord) + fsColor; // or can use multiply in another case
}
  • With this code, you can totally fine. But the problem turn out is, when you draw the texture only, you still have to set and send to the GLSL program the aColor data, similar with aTexCoord problem when I only want to set color to the vertex.
  • You can laugh with what I said, but the real issue is, when you use the smaller memory bandwidth, the percent I will hit the cache is more than when I use more data, there’re is many things involve with this topic, and this topic so too large, so I don’t want to talk about it in here, but about the basically it is.
  • And of course, less memory use is better for both CPU and GPU.
  • You can specify each vbo with diffirent Vertex Attribute Pointer but isn’t it terrible?
    For example:
// one VBO use texture only
glBindBuffer(buffer image);
glBindTexture(); // texture image
glVertexAttribPointer(); // setup for vertices
glVertexAttribPointer(); // setup for texture
glDraw...

// another VBO use color only
glBindBuffer(buffer vertices with colors);
glBindTexture(image faker); // texture image
glVertexAttribPointer(); // setup for vertices
glVertexAttribPointer(); // setup for colors
glDraw...
  • Doesn’t it horrible? I think it does.
  • Is there any other solution? I known the way we’re working with opengl is a nightmare(honestly), but I want it less terrify to make it easier to control when the source code is big.
#9

Are you aware that you can set constant vertex attribute values?:

That seems to address your concern.

That said, be sure to profile, and follow the trail where it leads. I think you’ll be surprised by what you find. The cost of puling in vertex attributes, for instance, is rarely a bottleneck.

Changing state (shaders, textures, etc.) is typically more expensive than the cost of pulling in vertex attributes.