Using the following GLSL Fragment Shader renders strange behaviour. The second continue is never executed - even if b is GL_TRUE. (This example is a reduced version of a bigger shader, that has some code inbetween both continues.)
Driver Version 335.23; GeForce GTX 660; Windows 8.1 64 bits
#version 330
out vec4 color;
uniform bool a;
uniform bool b;
void main() {
for (int i = 0; i < 3; ++i) {
// a = GL_TRUE and b = GL_TRUE
// This does not work
// THE TRIANGLE IS NOT DRAWN
if (!a)
continue;
if (b)
continue;
// This works
// THE TRIANGLE IS DRAWN
//if (!a || b)
// continue;
discard;
}
color = vec4(1.0, 0.0, 0.0, 1.0);
}
For completeness, I use the following vertex shader:
#version 330
in vec2 coords;
void main() {
gl_Position = vec4(coords, 0.0, 1.0);
}
and this C++ code (using SDL2 and glLoadGen) to execute the program:
#include "gl_core_4_4.h"
#include <cstdlib>
#include <SDL.h>
#include <string>
#include <fstream>
#include <sstream>
#include <memory>
static GLint compileShader(const std::string &path, GLenum shaderType) {
auto shader = glCreateShader(shaderType);
std::ifstream in;
std::string line;
std::ostringstream shaderSourceStream;
in.open(path);
while (in.good()) {
std::getline(in, line);
shaderSourceStream << line << "\n";
}
in.close();
std::string shaderSource = shaderSourceStream.str();
const char * shaderCStr = shaderSource.c_str();
glShaderSource(shader, 1, &shaderCStr, nullptr);
glCompileShader(shader);
GLint infoLogLength;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
if (infoLogLength) {
auto infoLogCStr = std::unique_ptr<GLchar[]>(new GLchar[infoLogLength]);
glGetShaderInfoLog(shader, infoLogLength, nullptr, infoLogCStr.get());
}
GLint status;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if (status != GL_TRUE) {
throw std::string("GL_COMPILE_STATUS for shader is not GL_TRUE: " + path);
}
return shader;
}
int main(int, char*[]) {
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
auto window = SDL_CreateWindow(
"Test",
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
1024, 768,
SDL_WINDOW_OPENGL);
auto context = SDL_GL_CreateContext(window);
ogl_LoadFunctions();
auto v = compileShader("vert.glsl", GL_VERTEX_SHADER);
auto f = compileShader("frag.glsl", GL_FRAGMENT_SHADER);
auto prog = glCreateProgram();
glAttachShader(prog, v);
glAttachShader(prog, f);
glLinkProgram(prog);
glUseProgram(prog);
GLint status;
glGetProgramiv(prog, GL_LINK_STATUS, &status);
if (status != GL_TRUE) {
throw std::string("...");
}
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
const float coords[] = {-0.5f, -0.5f, 0.5f, -0.5f, 0.0f, 0.5f};
GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(coords), coords, GL_STATIC_DRAW);
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
glUniform1i(glGetUniformLocation(prog, "a"), GL_TRUE);
glUniform1i(glGetUniformLocation(prog, "b"), GL_TRUE);
SDL_Event e;
for (;;) {
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, 6);
SDL_GL_SwapWindow(window);
while (SDL_PollEvent(&e))
;
}
return EXIT_SUCCESS;
}