Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
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);
}
This is not a problem with the shaders. However in a core profile OpenGL Context you have to create Vertex Array Object, since the default VAO (0) is not valid. This is not optional:
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glEnableVertexAttribArray(0); // Enables the buffer layout
glBindBuffer(GL_ARRAY_BUFFER, currentBuffer);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0)
You have to bind the VAO before the vertex specification. The vertex specification is stored in the VAO.
The vertex specification stored in the currently bound VAO is used when drawing a mesh. Hence, you need to make sure the VAO is bound before the drawing command as well:
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, 3);
Related
I am trying to simplify my example to show exact abnormal case. I am running this example on MacOS 10.14.6, compiling clang LLVM compiler, using GLFW3. Also I am trying to run same example on Windows 10/64 using SFML and got same error, therefore the problem is not in the environment
OpenGL version 4.1 ATI-2.11.20
Shading language version 4.10
Exact code where problem is
glUseProgram(id_shader);
glEnableVertexAttribArray(param_Position);
//HERE IS ERROR "OpenGL ERROR: 0x00000502 GL_INVALID_OPERATION" RAISED
glVertexAttribPointer(param_Position, 3, GL_FLOAT, (GLboolean) false, 0, vertices);
Here is source full code
#include <stdlib.h>
#include <OpenGL/gl3.h>
#include <GLFW/glfw3.h>
#include "engine/Camera.h"
static const char *get_error_string_by_enum(GLenum err)
{
switch (err) {
case GL_INVALID_ENUM :
return "GL_INVALID_ENUM";
case GL_INVALID_VALUE :
return "GL_INVALID_VALUE";
case GL_INVALID_OPERATION :
return "GL_INVALID_OPERATION";
case GL_STACK_OVERFLOW :
return "GL_STACK_OVERFLOW";
case GL_STACK_UNDERFLOW :
return "GL_STACK_UNDERFLOW";
case GL_OUT_OF_MEMORY :
return "GL_OUT_OF_MEMORY";
#ifdef GL_INVALID_FRAMEBUFFER_OPERATION
case GL_INVALID_FRAMEBUFFER_OPERATION :
return "GL_INVALID_FRAMEBUFFER_OPERATION";
#endif
default: {
return "UNKNOWN";
}
}
}
static void check_gl()
{
char line[300];
GLenum err;
err = glGetError();
if (err != GL_NO_ERROR) {
sprintf(line, "OpenGL ERROR: 0x%.8X %s", err, get_error_string_by_enum(err));
printf("%s\n", line);
exit(-1);
}
}
int main()
{
char line[2000];
unsigned int windowWidth = 1024;
unsigned int windowHeight = 1024;
GLFWwindow* window;
//SETUP WINDOW AND CONTEXT
if (!glfwInit()){
fprintf(stdout, "ERROR on glfwInit");
return -1;
}
glfwWindowHint(GLFW_SAMPLES, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
window = glfwCreateWindow(windowWidth, windowHeight, "OpenGL", NULL, NULL);
if (!window)
{
fprintf(stderr, "Unable to create window.");
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
sprintf(line, "OpenGL version %s\n", (const char *) glGetString(GL_VERSION));
fprintf(stdout, line);
sprintf(line, "Shading language version %s\n", (const char *) glGetString(GL_SHADING_LANGUAGE_VERSION));
fprintf(stdout, line);
//SETUP OPENGL
glViewport(0, 0, windowWidth, windowHeight);
glEnable(GL_BLEND);
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glDepthMask(true);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//SETUP SHADER PROGRAM
GLint success;
GLuint id_v = glCreateShader(GL_VERTEX_SHADER);
GLuint id_f = glCreateShader(GL_FRAGMENT_SHADER);
const char *vertex_shader_source = "#version 330\n"
"precision mediump float;\n"
"\n"
"in vec4 Position;\n"
"uniform mat4 MVPMatrix;\n"
"\n"
"void main()\n"
"{\n"
"\tgl_Position = MVPMatrix * Position;\n"
"\tgl_PointSize = 10.0;\n"
"}";
const char *fragment_shader_source = "#version 330\n"
"precision mediump float;\n"
"\n"
"uniform vec4 Color;\n"
"out vec4 FragCoord;\n"
"\n"
"void main()\n"
"{\n"
" FragCoord = Color;\n"
"}";
glShaderSource(id_v, 1, &vertex_shader_source, NULL);
glCompileShader(id_v);
glGetShaderiv(id_v, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(id_v, 2000, NULL, line);
fprintf(stderr, line);
exit(-1);
}
glShaderSource(id_f, 1, &fragment_shader_source, NULL);
glCompileShader(id_f);
glGetShaderiv(id_f, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(id_f, 2000, NULL, line);
fprintf(stderr, line);
exit(-1);
}
GLuint id_shader = glCreateProgram();
glAttachShader(id_shader, id_v);
glAttachShader(id_shader, id_f);
glLinkProgram(id_shader);
glGetProgramiv(id_shader, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(id_shader, 2000, NULL, line);
fprintf(stderr, "program link error");
fprintf(stderr, line);
exit(-1);
}
GLuint param_Position = glGetAttribLocation(id_shader, "Position");
GLuint param_MVPMatrix = glGetUniformLocation(id_shader, "MVPMatrix");
GLuint param_Color = glGetUniformLocation(id_shader, "Color");
sprintf(line, "Params: param_Position=%d param_MVPMatrix=%d param_Color=%d\n", param_Position, param_MVPMatrix, param_Color);
fprintf(stdout, line);
//SETUP MATRIX
Camera *c = new Camera();
c->setCameraType(CameraType::PERSPECTIVE);
c->setWorldSize(100, 100);
c->lookFrom(5, 5, 5);
c->lookAt(0, 0, 0);
c->setFOV(100);
c->setUp(0, 0, 1);
c->calc();
c->getResultMatrix().dump();
//SETUP TRIANGLE
float vertices[] = {
0, 0, 0,
1, 0, 0,
1, 1, 0
};
while (!glfwWindowShouldClose(window))
{
//CLEAR FRAME
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0.3f, 0.3f, 0.3f, 1.0f);
//RENDER TRIANGLE
glUseProgram(id_shader);
glUniformMatrix4fv(param_MVPMatrix, 1, (GLboolean) false, c->getResultMatrix().data);
glUniform4f(param_Color, 1.0f, 0.5f, 0.0f, 1.0f);
glEnableVertexAttribArray(param_Position);
check_gl();
//HERE IS ERROR "OpenGL ERROR: 0x00000502 GL_INVALID_OPERATION" RAISED
glVertexAttribPointer(param_Position, 3, GL_FLOAT, (GLboolean) false, 0, vertices);
check_gl();
glDrawArrays(GL_TRIANGLES, 0, 3);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
return 0;
}
Before line
glVertexAttribPointer(param_Position, 3, GL_FLOAT, (GLboolean) false, 0, vertices);
No errors detected before and just after this line GL_INVALID_OPERATION raised.
Program output is:
Environment versions:
OpenGL version 4.1 ATI-2.11.20
Shading language version 4.10
Shader param names:
Params: param_Position=0 param_MVPMatrix=1 param_Color=0
Matrix
-0.593333 -0.342561 -0.577350 -0.577350
0.593333 -0.342561 -0.577350 -0.577350
0.000000 0.685122 -0.577350 -0.577350
0.000000 0.000000 8.640252 8.660253
Error
OpenGL ERROR: 0x00000502 GL_INVALID_OPERATION
I already spent few days on that problem and have no more idea to put it on. I would be grateful for any advice and clarifications.
P.S. Here is glfwinfo output for my system
/glfwinfo -m3 -n2 --profile=compat
GLFW header version: 3.4.0
GLFW library version: 3.4.0
GLFW library version string: "3.4.0 Cocoa NSGL EGL OSMesa"
OpenGL context version string: "4.1 ATI-2.11.20"
OpenGL context version parsed by GLFW: 4.1.0
OpenGL context flags (0x00000001): forward-compatible
OpenGL context flags parsed by GLFW: forward-compatible
OpenGL profile mask (0x00000001): core
OpenGL profile mask parsed by GLFW: core
OpenGL context renderer string: "AMD Radeon R9 M370X OpenGL Engine"
OpenGL context vendor string: "ATI Technologies Inc."
OpenGL context shading language version: "4.10"
OpenGL framebuffer:
red: 8 green: 8 blue: 8 alpha: 8 depth: 24 stencil: 8
samples: 0 sample buffers: 0
Vulkan loader: missing
Since you use a core profile context (GLFW_OPENGL_CORE_PROFILE), the default Vertex Array Object 0 is not valid further you've to use Vertex Buffer Object.
When glVertexAttribPointer is called, then the vertex array specification is stored in the state vector of the currently bound vertex array object. The buffer which is currently bound to the target ARRAY_BUFFER is associated to the attribute and the name (value) of the object is stored in the state vector of the VAO.
In compatibility profile there exists the default vertex array object 0, which can be used at any time but this is not valid in a core profile context. Further it is not necessary in a compatibility profile to use a VBO, the last parameter of glVertexAttribPointer can be a pointer to the vertex data.
The easiest solution is to switch to a compatibility profile GLFW_OPENGL_COMPAT_PROFILE:
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE);
If you don't want to do that or your system doesn't provide that, then you've to read about Vertex Specification. Create a vertex buffer object a vertex array object before the program loop:
// vertex buffer object
GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// vertex array object
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vbo); // this is not necessary, because "vbo" is still bound
glVertexAttribPointer(param_Position, 3, GL_FLOAT, (GLboolean) false, 0, nullptr);
// the following is not necessary, you can let them bound
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
And use it in the loop to draw the mesh:
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, 3);
Hey there Im trying to draw a simple quad with 2 triangles in OpenGL through a vbo.
However I have looked at my code multiple times and I don't see what I am missing.
I ain't no Open GL expert, The code was working fine without any buffers however when I switchted to VBO Im not seeing anything anymore. OpenGL also doesn't provide any helpfull errors.
Image::Image(Graphics * GFX)
{
glm::vec2 corners[2];
corners[0] = glm::vec2(0, 0);
corners[1] = glm::vec2(1, 1);
vertices = new GLfloat[30]
{
//Vertices XYZ TexCoord X,Y
corners[0].x, corners[0].y, 0.0f, 0,0,
corners[0].x, corners[1].y, 0.0f, 0,1,
corners[1].x, corners[0].y, 0.0f, 1,0,
corners[1].x,corners[1].y,0.0f, 1,1,
corners[0].x, corners[1].y,0.0f, 0,1,
corners[1].x, corners[0].y, 0.0f, 1,0
};
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
//Setting up some stuff
const char *vertexShaderSource =
"attribute vec4 vPosition; \n"
"attribute vec2 vTexCoord; \n"
"void main() \n"
"{ \n"
" gl_Position = vPosition; \n"
"} \n";
const char *fragmentShaderSource =
"precision mediump float; \n"
"void main() \n"
"{ \n"
" gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); \n"
"} \n";
// Load and compile the vertex/fragment shaders
vertexShader = GFX->LoadShader(GL_VERTEX_SHADER, (const char*)vertexShaderSource);
fragmentShader = GFX->LoadShader(GL_FRAGMENT_SHADER, (const char*)fragmentShaderSource);
// Create the program object
programObject = glCreateProgram();
// now we have the V and F shaders attach them to the progam object
glAttachShader(programObject, vertexShader);
glAttachShader(programObject, fragmentShader);
// Link the program
glLinkProgram(programObject);
// Check the link status
// Link the program
GLint AreTheylinked;
glGetProgramiv(programObject, GL_LINK_STATUS, &AreTheylinked);
if (!AreTheylinked)
{
GLint RetinfoLen = 0;
// check and report any errors
glGetProgramiv(programObject, GL_INFO_LOG_LENGTH, &RetinfoLen);
if (RetinfoLen > 1)
{
GLchar* infoLog = (GLchar*)malloc(sizeof(char) * RetinfoLen);
glGetProgramInfoLog(programObject, RetinfoLen, NULL, infoLog);
fprintf(stderr, "Error linking program:\n%s\n", infoLog);
free(infoLog);
}
glDeleteProgram(programObject);
}
positionLocation = glGetAttribLocation(programObject, "vPosition");
textureCoordLocation = glGetAttribLocation(programObject, "vTexCoord");
if (glGetError() == GL_NO_ERROR) {}
else
printf("Init failed!\n");
//End setting up
}
Image::~Image()
{
}
void Image::Draw()
{
std::cout << "Calling Draw on Image" << std::endl;
glUseProgram(programObject);
glEnable(GL_DEPTH_TEST);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
GLsizei stride = (5) * sizeof(GLfloat);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, stride, 0);
glEnableVertexAttribArray(0);
glDrawArrays(GL_TRIANGLES, 0, 6);
if (glGetError() != GL_NO_ERROR)
{
printf("UI Draw error\n");
}
glDisableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
And how I am loading the shaders:
GLuint Graphics::LoadShader(GLenum type, const char *shaderSrc)
{
// 1st create the shader object
GLuint TheShader = glCreateShader(type);
if (TheShader == 0) return FALSE; // can't allocate so stop.
// pass the shader source then compile it
glShaderSource(TheShader, 1, &shaderSrc, NULL);
glCompileShader(TheShader);
GLint IsItCompiled;
// After the compile we need to check the status and report any errors
glGetShaderiv(TheShader, GL_COMPILE_STATUS, &IsItCompiled);
if (!IsItCompiled)
{
GLint RetinfoLen = 0;
glGetShaderiv(TheShader, GL_INFO_LOG_LENGTH, &RetinfoLen);
if (RetinfoLen > 1)
{ // standard output for errors
char* infoLog = (char*)malloc(sizeof(char) * RetinfoLen);
glGetShaderInfoLog(TheShader, RetinfoLen, NULL, infoLog);
fprintf(stderr, "Error compiling this shader:\n%s\n", infoLog);
free(infoLog);
}
glDeleteShader(TheShader);
return FALSE;
}
return TheShader;
}
It worked fine without a buffer previously, and saw a white square by using:
glVertexAttribPointer(0, 6, GL_FLOAT, GL_FALSE, 0, vertices);
But now I want to add texture coordinates to my quad through a VBO but nothing shows anymore.
Smoothy101
Your buffer creation looks fine - the problem is your attribute pointer setup. You've added texture coordinates which has changed data layout for each vertex, but you've not handled that in your code.
You need something like this:
glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, stride, 0);
glVertexAttribPointer(textureCoordLocation, 2, GL_FLOAT, GL_FALSE, stride, 8);
... not this:
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, stride, 0);
For a few days now, I've been struggling with compute shaders and buffers. I've looked through multiple examples of their usage, such as in "The OpenGL redbook 8th edition" and on the threads "OpenGL vertices in shader storage buffer" and "OpenGL Compute Shader SSBO," but I can't seem to get this working.
I'm trying to make, for now, a simple program that can generate vertices by invoking a compute shader, store those generated vertices in an SSBO, pass those vertices to a vertex shader, and then go through the rest of the pipeline to make a single, stationary image, which, in this case, is just a line. However, after compiling the program, only a dot at (0,0) is shown.
The compute shader:
#version 430 core
layout(std430, binding = 0) buffer data
{
float coordinate_array[200][3];
};
layout(local_size_x=20, local_size_y=1, local_size_z=1) in;
void main(void)
{
uint x = gl_GlobalInvocationID.x;
if(x%2 == 0)
{
coordinate_array[x][0] = -.5;
coordinate_array[x][0] = -.5;
coordinate_array[x][0] = 0;
}
else
{
coordinate_array[x][0] = .5;
coordinate_array[x][0] = .5;
coordinate_array[x][0] = 0;
}
}
Program:
char *source;
GLuint vertexShader, fragmentShader, computeShader;
GLuint program, computeShaderProgram;
GLuint computeShaderBuffer;
numVertices = 200;
dimension = 3;
size = sizeof(float**)*numVertices*dimension;
//Create the buffer the compute shader will write to
glGenBuffers(1, &computeShaderBuffer);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, computeShaderBuffer);
glBufferData(GL_SHADER_STORAGE_BUFFER, size, NULL, GL_STATIC_DRAW);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, computeShaderBuffer);
//Create the compute shader
computeShader = glCreateShader(GL_COMPUTE_SHADER);
source = getSource(computeShaderSrc);
glShaderSource(computeShader, 1, &source, NULL);
glCompileShader(computeShader);
//Create and dispatch the compute shader program
computeShaderProgram = glCreateProgram();
glAttachShader(computeShaderProgram, computeShader);
glLinkProgram(computeShaderProgram);
glUseProgram(computeShaderProgram);
glDispatchCompute(numVertices/20, 1, 1);
//Generate the vertex array object
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
//Use buffer as a set of vertices
glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT);
glBindBuffer(GL_ARRAY_BUFFER, computeShaderBuffer);
//Create the vertex shader
vertexShader = glCreateShader(GL_VERTEX_SHADER);
source = getSource(vertexShaderSource);
glShaderSource(vertexShader, 1, &source, NULL);
//Create the fragment shader
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
source = getSource(fragmentShaderSource);
glShaderSource(fragmentShader, 1, &source, NULL);
glCompileShader(fragmentShader);
//Create the program to draw
program = glCreateProgram();
glAttachShader(program, vertexShader);
glAttachShader(program, fragmentShader);
glLinkProgram(program);
glUseProgram(program);
//Enable the vertex array
glVertexAttribPointer(0, dimension, GL_FLOAT, 0, 0, (void*)0);
glEnableVertexAttribArray(0);
//Draw it
glClear(GL_COLOR_BUFFER_BIT);
glBindVertexArray(VAO);
glDrawArrays(GL_POINTS, 0, numVertices);
glFlush();
Vertex Shader:
#version 430 core
layout(location = 0) in vec4 vPosition;
void main()
{
gl_Position = vPosition;
}
In this sample, I try to use an SSBO to hold the 2 endpoints of a line segment (-.5, -.5) (.5, .5). The shader storage buffer holds this segment 100 times instead of just once; I thought there was a dispatch minimum I wasn't meeting.
If I call glGetError(program) or glGetError(computeShaderProgram), it returns GL_NO_ERROR. Also, the shaders compile successfully and both programs link without error. It does, however, warn me that extension 420pack is required in the compute shader for some reason. When I used #extension ARB_420pack (not my exact writing), it didn't get rid of the warning. My drivers are up-to-date and I have a Radeon R9 270x (OpenGL 4.4). I'm using MinGW and C to create this program, but I do know some C++.
Does anyone have any ideas on what I'm doing wrong?
Does this seem right in your CS:
if(x%2 == 0)
{
coordinate_array[x][0] = -.5;
coordinate_array[x][0] = -.5;
coordinate_array[x][0] = 0;
}
else
{
coordinate_array[x][0] = .5;
coordinate_array[x][0] = .5;
coordinate_array[x][0] = 0;
}
look carefully at the indices you assign to. It's always [x][0]. Clearly you want at least one index to vary.
I am getting an error when trying to use VAO's inside of SFML and not sure if it is SFML or it is my own opengl code
GLenum err = glewInit();
if (err != GLEW_OK)
{
std::cout << "NOT WORKING" << std::endl;
}
std::vector<sf::Vector3f> g_vertext_buffer_data;
g_vertex_buffer_data.push_back({ -1.0f, -1.0f, 0.0f });
g_vertex_buffer_data.push_back({1.0f, -1.0f, 0.0f});
g_vertex_buffer_data.push_back({ 0.0f, 1.0f, 0.0f });
const char* vertexShaderSource =
"#version 330\n\
in vec4 position;\
void main(void){\ gl_Position = position;\
}";
// compile fragment shader source
const GLchar* fragmentShaderSource =
"#version 330\n\
void main(void) {\
out vec4 fragcolor; fragcolor= vec4(1.0,1.0,1.0,1.0);\
}";
/* Creating Shader */
this->programId = glCreateProgram();
this->vId = glCreateShader(GL_VERTEX_SHADER);
this->fId = glCreateShader(GL_FRAGMENT_SHADER);
/* Get Shader Size */
int vertexShaderLength = strlen(vertexShaderSource);
int fragmentShaderLength = strlen(fragmentShaderSource);
/* Loading and binding shader */
glShaderSource(this->vId, 1, &vertexShaderSource, NULL);
glShaderSource(this->fId, 1, &fragmentShaderSource, NULL);
/* Compile Shaders */
glCompileShader(vId);
glCompileShader(fId);
/* Attach Shaders */
glAttachShader(this->programId, this->vId);
glAttachShader(this->programId, this->fId);
/* Linkg program */
glLinkProgram(this->programId);
/* Use and bind attribute */
glUseProgram(this->programId);
this->positionId = glGetAttribLocation(this->programId, "position");
glUseProgram(0);
/* VAO Time */
glGenVertexArrays(1, &this->vaoId);
glBindVertexArray(this->vaoId);
/* VBO Time assigning to VAO */
glGenBuffers(1, &this->vboId);
glBindBuffer(GL_ARRAY_BUFFER, this->vboId);
glBufferData(GL_ARRAY_BUFFER, g_vertex_buffer_data.size() * sizeof(sf::Vector3f), &g_vertex_buffer_data[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(this->positionId);
glVertexAttribPointer(this->positionId, 2, GL_FLOAT, GL_FALSE, sizeof(sf::Vector3f), 0);
/* Close out bindings */
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
while(1)
{
glUseProgram(this->programId);
glBindVertexArray(this->vaoId);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
glUseProgram(0);
gameWindow.glPushStates();
}
The error code I get is: opengl error in user code (1282)
I have changed the size() issue that was brought up in the blBufferData() but still am getting the issue.
There is at least a problem with the size that is passed to glBufferData:
glBufferData(GL_ARRAY_BUFFER,
sizeof(g_vertex_buffer_data) * sizeof(sf::Vector3f),
g_vertex_buffer_data[0], GL_STATIC_DRAW);
sizeof(g_vertex_buffer_data) is equal to sizeof(std::vector<?>) which is the size of the vector object and not the size of the data contained. Try using
glBufferData(GL_ARRAY_BUFFER,
g_vertex_buffer_data.size() * sizeof(sf::Vector3f),
g_vertex_buffer_data[0], GL_STATIC_DRAW);
Another thing: In OpenGL 3.3 Core Profile there is no gl_FragColor variable. You will have to define an out variable.
Next: Your vertex shader seems to be empty. You have to write to gl_Position otherwise nothing will be shown.
Possible error codes for glGetAttribLocation are:
GL_INVALID_OPERATION
Which don't have a fixed value. Try to get the error string with gluErrorString() or take a look in the header to which of those 1282 maps.
• check your shader got compiled without error?
• check your shader got linked without error?
What type have positionId? All object id's must be GLuint type.
And btw allways enable shader compilation-linking error check, and debug will be more informative.
I do that in this way (OpenGL-ES 2.0):
m_nVertexShader = glCreateShader(GL_VERTEX_SHADER);
m_nPixelShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(m_nVertexShader, 1, &lpszVertexBuffer, NULL);
glShaderSource(m_nPixelShader, 1, &lpszFragmentBuffer, NULL);
glCompileShader(m_nVertexShader);
int iIsOk = 0;
glGetShaderiv(m_nVertexShader, GL_COMPILE_STATUS, &iIsOk);
if(!iIsOk)
{
GLint infoLen = 0;
glGetShaderiv(m_nVertexShader, GL_INFO_LOG_LENGTH, &infoLen);
if(infoLen > 1)
{
char* infoLog = (char*)malloc(sizeof(char) * infoLen);
glGetShaderInfoLog(m_nVertexShader, infoLen, NULL, infoLog);
QMessageBox::warning(this, QString("Error"),
QString(infoLog), QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes);
free(infoLog);
}
glDeleteShader(m_nVertexShader);
return;
}
glCompileShader(m_nPixelShader);
glGetShaderiv(m_nPixelShader, GL_COMPILE_STATUS, &iIsOk);
if(!iIsOk)
{
GLint infoLen = 0;
glGetShaderiv(m_nPixelShader, GL_INFO_LOG_LENGTH, &infoLen);
if(infoLen > 1)
{
char* infoLog = (char*)malloc(sizeof(char) * infoLen);
glGetShaderInfoLog(m_nPixelShader, infoLen, NULL, infoLog);
QMessageBox::warning(this, QString("Error"),
QString(infoLog), QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes);
free(infoLog);
}
glDeleteShader(m_nPixelShader);
return;
}
m_nProgram = glCreateProgram();
glAttachShader(m_nProgram, m_nVertexShader);
glAttachShader(m_nProgram, m_nPixelShader);
glBindAttribLocation(m_nProgram, 0, "rm_Vertex");
glLinkProgram(m_nProgram);
glGetProgramiv(m_nProgram, GL_LINK_STATUS, &iIsOk);
// Fail to pass status validation
if(!iIsOk)
{
GLint infoLen = 0;
glGetProgramiv(m_nProgram, GL_INFO_LOG_LENGTH, &infoLen);
if(infoLen > 1)
{
char* infoLog = (char*)malloc(sizeof(char) * infoLen);
glGetProgramInfoLog(m_nProgram, infoLen, NULL, infoLog);
QMessageBox::warning(this, QString("Error"),
QString(infoLog), QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes);
free(infoLog);
}
glDeleteProgram(m_nProgram);
return;
}
glUseProgram(m_nProgram);
As you use GLSL 3.3, fist you must specify fragment rendertarget output by calling
glBindFragDataLocation(this->programId, 0, "fragcolor");
Secondly your fragment shader must be like
"#version 330
out vec4 fragcolor;
void main(void) {
fragcolor= vec4(1.0,1.0,1.0,1.0);
}
The example of using this kind of shaders is on OpenGL 3.3 + GLSL 1.5 Sample.
I'm trying to get a small triangle to display.
Here is my initialization code:
void PlayerInit(Player P1)
{
glewExperimental = GL_TRUE;
glewInit();
//initialize buffers needed to draw the player
GLuint vao;
GLuint buffer;
glGenVertexArrays(1, &vao);
glGenBuffers(1, &buffer);
//bind the buffer and vertex objects
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
//Set up a buffer to hold 6 floats for position, and 9 floats for color
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*18, NULL, GL_STATIC_DRAW);
//push the vertices of the player into the buffer
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*9, CalcPlayerPoints(P1.GetPosition()));
//push the color of each player vertex into the buffer
glBufferSubData(GL_ARRAY_BUFFER, sizeof(float)*9, sizeof(float)*9, CalcPlayerColor(1));
//create and compile the vertex/fragment shader objects
GLuint vs = create_shader("vshader.glsl" ,GL_VERTEX_SHADER);
GLuint fs = create_shader("fshader.glsl" ,GL_FRAGMENT_SHADER);
//create a program object and link the shaders
GLuint program = glCreateProgram();
glAttachShader(program, vs);
glAttachShader(program, fs);
glLinkProgram(program);
//error checking for linking
GLint linked;
glGetProgramiv(program, GL_LINK_STATUS, &linked);
if(!linked)
{
std::cerr<< "Shader program failed to link" <<std::endl;
GLint logSize;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logSize);
char* logMsg = new char[logSize];
glGetProgramInfoLog(program, logSize, NULL, logMsg);
std::cerr<< logMsg << std::endl;
delete [] logMsg;
exit(EXIT_FAILURE);
}
glUseProgram(program);
//create attributes for color and position to pass to shaders
//enable each attribute
GLuint Pos = glGetAttribLocation( program, "vPosition");
glEnableVertexAttribArray(Pos);
GLuint Col = glGetAttribLocation( program, "vColor");
glEnableVertexAttribArray(Col);
//set a pointer at the proper offset into the buffer for each attribute
glVertexAttribPointer(Pos, 3, GL_FLOAT, GL_FALSE, 0, (const GLvoid*) (sizeof(float)*0));
glVertexAttribPointer(Col, 3, GL_FLOAT, GL_FALSE, 0, (const GLvoid*) (sizeof(float)*9));
}
I don't have much experience writing shader linkers, so I think that is where the problem might be. I have some error checking in the shader loader, and nothing comes up. So I think that is fine.
Next I have my display and main function:
//display function for the game
void GameDisplay( void )
{
//set the background color
glClearColor(1.0, 0.0, 1.0, 1.0);
//clear the screen
glClear(GL_COLOR_BUFFER_BIT);
//Draw the Player
glDrawArrays(GL_TRIANGLES, 0, 3);
glutSwapBuffers();
}
//main function
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowSize(500, 500);
glutCreateWindow("Asteroids");
Player P1 = Player(0.0, 0.0);
PlayerInit(P1);
glutDisplayFunc(GameDisplay);
glutMainLoop();
return 0;
}
Vertex shader :
attribute vec3 vPosition;
attribute vec3 vColor;
varying vec4 color;
void main()
{
color = vec4(vColor, 1.0);
gl_Position = vec4(vPosition, 1.0);
}
Fragment shader
varying vec4 color;
void main()
{
gl_FragColor = color;
}
That's all of the relevant code. CalcPlayerPoints just returns a float array of size 9 to hold the triangle coordinates. CalcPlayerColor does something similar.
One last problem that may help with diagnosing the problem is that whenever I try to exit the program by closing the window of the application, I get a breakpoint in the glutmainloop, however if I close the console window, it exits fine.
Edit: I added the shaders for reference.
Edit: I am using opengl version 3.1
Without the shaders, we can't say if the faulty code isn't GLSL (bad vertices transformations, etc.)
Have you tried checking glGetError to see if the problem doesn't come from your initialization code ?
Maybe try to set the output of your fragment shader to, say, vec4(1.0, 0.0, 0.0, 1.0) to check if its normal output is ill-formed.
Your last problem seems to unveil an undefined behavior, like bad memory allocation/deallocation, which may take place in your Player class (by the way consider passing the object as a reference in your initialization code, because it may at the moment trigger a shallow copy and then a double-free of some pointer).
Turns out there was something wrong with how I was returning the array of vertices from the function used to compute them. The rest of the code worked fine after that fix.