I'm trying to get OpenGL to render a basic triangle with shaders on my newer Macbook Pro with the M1 chip. I'm stuck using Qt Creator as well.
I was able to set it up and get a basic Fixed-Pipeline scene rendering, but when I changed the version to use modern OpenGL I get that the version is 4.1, even though I set it to 3.2.
Here's how I set the version:
QSurfaceFormat format;
format.setDepthBufferSize(24);
format.setStencilBufferSize(8);
format.setProfile(QSurfaceFormat::CoreProfile);
format.setMajorVersion(3);
format.setMinorVersion(2);
QSurfaceFormat::setDefaultFormat(format);
this->setFormat(format); // must be called before the widget or its parent window gets shown
When I print out the shader sources I can see that I'm getting exactly what I put into my vertex shader and fragment shader files, so I know that I'm loading in the files correctly. Here's how I'm using them inside of my Shader class:
programID = glCreateProgram(); // Creates the program ID
vs = glCreateShader(GL_VERTEX_SHADER); // Creates the vertex shader
fs = glCreateShader(GL_FRAGMENT_SHADER); // Creates the fragment shader
// Shader reading code removed...
const char* vSrc = vSource.c_str();
int size = vSource.size();
glShaderSource(vs, 1, &vSrc, &size);
glCompileShader(vs);
int result;
glGetShaderiv(vs, GL_COMPILE_STATUS, &result);
if (result == GL_FALSE)
{
int length;
glGetShaderiv(vs, GL_INFO_LOG_LENGTH, &length);
char* msg = new char[length];
glGetShaderInfoLog(vs, length, &length, msg);
std::cout << "Vertex Shader Message:\n" << msg << std::endl;
exit(1);
}
const char* fSrc = fSource.c_str();
int size2 = fSource.size();
glShaderSource(fs, 1, &fSrc, &size2);
glCompileShader(fs);
int result2;
glGetShaderiv(fs, GL_COMPILE_STATUS, &result2);
if (result2 == GL_FALSE)
{
int length;
glGetShaderiv(fs, GL_INFO_LOG_LENGTH, &length);
char* msg = new char[length];
glGetShaderInfoLog(fs, length, &length, msg);
std::cout << "Fragment Shader Message:\n" << msg << std::endl;
exit(1);
}
glAttachShader(programID, vs);
glAttachShader(programID, fs);
glLinkProgram(programID);
glValidateProgram(programID);
And then in my initOpenGL function I have:
float positions[6] =
{
-0.5, -0.5,
0.0, 0.5,
0.5, -0.5
};
glGenBuffers(1, ¤tBuffer); // Generates the buffer
glBindBuffer(GL_ARRAY_BUFFER, currentBuffer); // Binds it before we use it
glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(float), positions, GL_STATIC_DRAW); // Sends the data to OpenGL
glEnableVertexAttribArray(0); // Enables the buffer layout
glBindBuffer(GL_ARRAY_BUFFER, currentBuffer);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0); // Tells OpenGL how we stored the data
s = new Shader("main.vsh", "main.fsh");
glUseProgram(s->getShaderID());
Then, I render the data with the following call in my render function:
glDrawArrays(GL_TRIANGLES, 0, 3);
Here is the vertex shader code:
#version 410 core
layout (location = 0) in vec4 position;
void main()
{
gl_Position = position;
}
Here is the fragment shader code:
#version 410 core
layout (location = 0) out vec4 color;
void main(void)
{
color = vec4(1.0, 0.0, 0.0, 1.0);
}