OpenGL glAttachShader 1281 Error - c++

I am trying to create a OpenGL framework for a game that includes a shader function that parses a vertex Shader and a vertex fragment.
using the OpenGL Call to isolate the error and report a bug break at the line.
#define ASSERT(x) if (!(x)) __debugbreak();
#define GLCall(x) GLClearError();\
x;\
ASSERT(GLLogCall(#x, __FILE__, __LINE__))
when the debug is reported, "[OPENGL Error]: <1281>", I get an error at this code:
GLCall(glAttachShader(program, vs));
which is used in this function:
static unsigned int CreateShader(const std::string& vertexShader, const
std::string& fragmentShader)
{
GLCall(unsigned int program = glCreateProgram());
GLCall(unsigned int vs = CompileShader(GL_VERTEX_SHADER, vertexShader));
GLCall(unsigned int fs = CompileShader(GL_FRAGMENT_SHADER, fragmentShader));
GLCall(glAttachShader(program, vs));
GLCall(glAttachShader(program, fs));
GLCall(glLinkProgram(program));
GLCall(glValidateProgram(program));
GLCall(glDeleteShader(vs));
GLCall(glDeleteShader(fs));
return program;
}
On the console window, it displays:
"Failed to compile shader! vertex"
ERROR: 0:7 'position' : undeclared indentified
ERROR: 0:7 'assign' : cannot convert from 'float' to 'Position 4-component vector of float'"
However, it still produces a blue quad on my screen.

Make sure that your shader is being properly updated whenever you're building your code. Open the build directory and look for the shader file that you're using, and ensure that changes you're making to the source shader are reflected in the build version. A common error with shaders is that they are copied when the files are first created and then not updated.
I am following the same series by TheCherno on YouTube as you, and I've been using CMake as my build system. It copied over the shader file when I first created it, but hasn't since. By adding the below line to my CMakeLists.txt I ensure that if there are any changes to the shader file that CMake will update the file.
configure_file(${PROJECT_SOURCE_DIR}/res/shaders/shader.shader ${PROJECT_BINARY_DIR}/res/shaders/shader.shader COPYONLY)

Related

Problem trying to open a file with ifstream using CMake

/*
Defines the class Shader.
*/
I am developing an application in C++ with OpenGL and CMake. The structure of my directories is:
tanx
CMakeLists.txt
ext (contains GLFW and glad)
src
TanX.cpp
TanX.h
math (contains a couple of math methods; not very relevant for my problem)
Shader
Shader.h
vertex.glsl
fragment.glsl
CMakeLists.txt
Shader.h ist mainly supposed to read vertex and fragment shader sources from files, compile them and link them to a Shader program. It looks like this:
#ifndef _SHADER_H
#define _SHADER_H
#include <string>
#include <exception>
#include <fstream>
#include <glad.h>
class shader_exception :std::exception {
private:
const char* text;
public:
shader_exception(const char* text)
: text(text) {}
virtual const char* what() const {
return text;
}
};
class Shader {
private:
std::string* vertex_source = new std::string();
std::string* fragment_source = new std::string();
unsigned int vao, vbo, vertex_shader, fragment_shader, program;
public:
Shader(const char* vertex_source_path, const char* fragment_source_path) {
std::ifstream file_reader;
file_reader.open(vertex_source_path);
std::string line;
if (file_reader.is_open()) {
while (getline(file_reader, line)) {
vertex_source->append(line + "\n");
}
file_reader.close();
}
else
throw shader_exception("Could not open vertex shader source file");
file_reader.open(fragment_source_path); // this is where I get an unhandled exception dialog box
if (file_reader.is_open()) {
while (getline(file_reader, line)) {
fragment_source->append(line + "\n");
}
file_reader.close();
}
else
throw shader_exception("Could not open fragment shader file");
const char** vertex_source_c = (const char**)malloc(vertex_source->size());
*vertex_source_c = vertex_source->c_str();
const char** fragment_source_c = (const char**)malloc(fragment_source->size());
*fragment_source_c = fragment_source->c_str();
vertex_shader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex_shader, 1, vertex_source_c, NULL);
glCompileShader(vertex_shader);
int success;
glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &success);
char infoLog[512];
if (!success) {
glGetShaderInfoLog(vertex_shader, 512, NULL, infoLog);
throw shader_exception(infoLog);
}
glShaderSource(fragment_shader, 1, fragment_source_c, NULL);
glCompileShader(fragment_shader);
glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(fragment_shader, 512, NULL, infoLog);
throw shader_exception(infoLog);
}
program = glCreateProgram();
glAttachShader(program, vertex_shader);
glAttachShader(program, fragment_shader);
glLinkProgram(program);
glGetProgramiv(program, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(program, 512, NULL, infoLog);
throw shader_exception(infoLog);
}
glDeleteShader(vertex_shader);
glDeleteShader(fragment_shader);
}
Shader() = delete;
void use()
{
glUseProgram(program);
}
~Shader() {
glDeleteProgram(program);
}
};
#endif
In TanX.cpp, I try to create a Shader object like this:
Shader shader("vertex.glsl", "fragment.glsl");
As you can see, the shader source files I'd like to use are vertex.glsl and fragment.glsl which are located in the "Shader" - folder. In order to make them usable to ifstream, the CMakeLists.txt file in the Shader-folder looks like this (This is one of the options mentioned here to make files usable for the program):
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/vertex.glsl ${CMAKE_CURRENT_BINARY_DIR} COPYONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fragment.glsl ${CMAKE_CURRENT_BINARY_DIR} COPYONLY)
The top-level CMakeLists.txt file also contains
add_subdirectory("TanX/src/Shader")
so that the CMakeLists.txt file in Shader is executed.
The problem is that when I try to run my code in Visual Studio, I get an unhandled exception in the Shader.h file, at line 45 (where it tries to open fragment.glsl). It is a shader_exception, so apparently opening vertex.glsl failed. The details of the "Exception Unhandled" - Dialog Box: "Unhandled exception at 0x00007FFF43E4A388 in TanX.exe: Microsoft C++ exception: shader_exception at memory location 0x00000028896FF608. occurred". Now I have two questions
1) What do I neeed to do to get ifstream to open vertex.glsl (and then fragment.glsl after that)?
2) Why do I even get an unhandled exception error, shouldn't construction of the Shader-object fail as soon as the exception gets thrown and that lead to the program not even reach line 45?
Right off the bat, this ...
Shader* shader;
try {
*shader = Shader("vertex.glsl", "fragment.glsl");
}
... is undefined behavior, because you are dereferencing an uninitialized pointer (i.e., you haven't allocated any storage for the Shader object). This may not be the only problem but it is a critical one that must be fixed before you can debug further (because the behavior of the program afterward is unpredictable).
You probably meant to write:
shader = new Shader(...);
(And really you should use std::unique_ptr for this rather than a bare pointer, but this is veering out of the scope of the original question. Among other benefits, it makes this kind of error easier to spot and avoid.)
As for other problems, have you checked that the program is run in the directory where the .glsl files are located? Relative paths passed to file streams are interpreted relative to the program's current working directory, not relative to the location of the original source file.
By my count, line 45 is ...
}
... so something seems to be misaligned. It would be helpful to post the actual program output and exception information (or dialog box contents) along with line numbers or an annotation showing the line the debugger is indicating.
The problem was where I put the files to. I put them into the bin folder of the Shader folder, but as it is implemented in the header, the correct place is the bin folder of the top-level folder.

‘GL_VERTIEX_SHADER’ was not declared in this scope - when it is <--It was a typo.

This is really weird,
line 1752 of glew.h:
#define GL_VERTEX_SHADER 0x8B31
Under the GL_VERSION_2_0 header guard
I have this code:
GLenum err = glewInit();
if(GLEW_OK != err) {
::std::cout<<"Error: "<<glewGetErrorString(err)<<"\n";
}
//GLuint shader = glCreateShader(GL_VERTIEX_SHADER); <--FAILS
GLuint shader = glCreateShader(0x8b31); <--WORKS
::std::cout<<"Shader: "<<shader<<"\n"<<"Errorstr: "<<
glewGetErrorString(glGetError())<<"\n";
#ifdef GL_VERSION_2_0
::std::cout<<"OKAY I have 2.0\n";
#endif
::std::cout<<glGetString(GL_VERSION)<<"\n";
Output:
Shader: 1
Errorstr: No error
OKAY I have 2.0
4.4.0 NVIDIA 331.38
If I use GL_VERTEX_SHADER however I get a symbol not found, weirdly my IDE can't find it either.
I've just noticed, I actually spelled "VERTEX" wrong. It works now. I feel really silly.
It took a title to make me see that though

OpenGL and SDL '#version required and missing' but working in debug

I'm fairly noobish with C++ so it's probably a bit too early to get into this sorta thing, but anyway. I've been working on setting up a simple triangle in OpenGL and SDL but I have some weird things happening already. The first thing is that when I compile it I get one of three errors:
Line 194: ERROR: Compiled vertex shader was corrupt.
Line 156: ERROR: 0:1: '' : #version required and missing. ERROR: 0:1: '<' : syntax error syntax error
Line 126: ERROR: 0:1: '' : #version required and missing.
ERROR: 0:1: 'lour' : syntax error syntax error
Like literally I just repeatedly hit the build button and it seems completely random whether it displays one or the other of the messages. Ok, so that's weird but what's weirder is that when I run it in debug mode (i.e I put a breakpoint and step through everything) it works perfectly, for no apparent reason.
So, I've come to the conclusion that I've done something stupid with memory, but in any case here is the relevant code (ask if you want to see more):
Read File Function
std::string readFile(std::string name) {
std::ifstream t1(name.c_str());
if (t1.fail()) {
std::cout << "Error loading stream" << "\n";
}
std::stringstream buffer;
buffer << t1.rdbuf();
std::string src = buffer.str();
std::cout << src << std::endl;
return src;
}
Compile Shaders
const char *vSource = readFile("vertexShader.gl").c_str();
// Read fragment shader
const char *fSource = readFile("fragmentShader.gl").c_str();
GLuint vs = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vs, 1, &vSource, NULL);
glCompileShader(vs);
GLint isCompiled = 0;
glGetShaderiv(vs, GL_COMPILE_STATUS, &isCompiled);
if(isCompiled == GL_FALSE) { // ... Error stuff here...
N.B there's a fragment shader compiling bit which looks exactly the same. Lines 126 and 156 are in the error stuff part of the vertex and fragment shaders respectively.
Link Shaders
shader_programme = glCreateProgram();
glAttachShader(shader_programme, vs);
glAttachShader(shader_programme, fs);
glLinkProgram(shader_programme);
GLint isLinked = 0;
glGetProgramiv(shader_programme, GL_LINK_STATUS, (int *)&isLinked);
if(isLinked == GL_FALSE) { // ... Error stuff ... }
glDetachShader(shader_programme, vs);
glDetachShader(shader_programme, fs);
You can see the shaders if you want but they work (as in the fragment shader shows the correct colour in debug mode) so I don' think that they are the problem.
I'm on OSX using SDL2, OpenGL v3.2, GLSL v1.50 and Xcode 4 (and yes I did the text file thing if you know what I mean).
Sorry for posting a lot of code - if anyone has any tips on how to debug memory leaks in Xcode that might help, but thanks anyway :)
you throw away the strings as soon as you read them leading to the vSource referencing deleted memory (and undefined behavior), instead keep the sources as std::string while you need the char* to remain valid:
std::string vSource = readFile("vertexShader.gl");
char* vSourcecharp = vSource.c_str();
// Read fragment shader
std::string fSource = readFile("fragmentShader.gl");
char* fSourcecharp = fSource.c_str();
GLuint vs = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vs, 1, &vSourcecharp, NULL);
glCompileShader(vs);

QGLShaderProgram will not compile any shader since upgrading to Qt5

I am finding that QGLShaderProgram is consistently failing to compile any shader and providing no error log. Here are the symptoms:
QGLShaderProgram reports that it failed to compile but produces an empty error log. If I try to bind the shader an exception is thrown.
I can compile a shader using glCompileShader without problem. However, the first time I try to compile this way after QGLShaderProgram has failed, fails with this error log:
ERROR: error(#270) Internal error: Wrong symbol table level
ERROR: 0:2: error(#232) Function declarations cannot occur inside of functions:
main
ERROR: error(#273) 2 compilation errors. No code generated
Following that one failure, the next time I try to compile using glCompileShader works fine.
The problem has arisen only since upgrading from Qt 4.8 to 5.2. Nothing else has changed on this machine.
I have tested on two PCs, one with an ATI Radeon HD 5700, the other with an AMD FirePro V7900. The problem only appears on the Radeon PC.
Here is my test code demonstrating the problem:
main.cpp
#include <QApplication>
#include "Test.h"
int main(int argc, char* argv[])
{
QApplication* app = new QApplication(argc, argv);
Drawer* drawer = new Drawer;
return app->exec();
}
Test.h
#pragma once
#include <qobject>
#include <QTimer>
#include <QWindow>
#include <QOpenGLContext>
#include <QOpenGLFunctions>
class Drawer : public QWindow, protected QOpenGLFunctions
{
Q_OBJECT;
public:
Drawer();
QTimer* mTimer;
QOpenGLContext* mContext;
int frame;
public Q_SLOTS:
void draw();
};
Test.cpp
#include "Test.h"
#include <QGLShaderProgram>
#include <iostream>
#include <ostream>
using namespace std;
Drawer::Drawer()
: mTimer(new QTimer)
, mContext(new QOpenGLContext)
, frame(0)
{
mContext->create();
setSurfaceType(OpenGLSurface);
mTimer->setInterval(40);
connect(mTimer, SIGNAL(timeout()), this, SLOT(draw()));
mTimer->start();
show();
}
const char* vertex = "#version 110 \n void main() { gl_Position = gl_Vertex; }";
const char* fragment = "#version 110 \n void main() { gl_FragColor = vec4(0.0,0.0,0.0,0.0); }";
void Drawer::draw()
{
mContext->makeCurrent(this);
if (frame==0) {
initializeOpenGLFunctions();
}
// Compile using QGLShaderProgram. This always fails
if (frame < 5)
{
QGLShaderProgram* prog = new QGLShaderProgram;
bool f = prog->addShaderFromSourceCode(QGLShader::Fragment, fragment);
cout << "fragment "<<f<<endl;
bool v = prog->addShaderFromSourceCode(QGLShader::Vertex, vertex);
cout << "vertex "<<v<<endl;
bool link = prog->link();
cout << "link "<<link<<endl;
}
// Manual compile using OpenGL direct. This works except for the first time it
// follows the above block
{
GLuint prog = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(prog, 1, &fragment, 0);
glCompileShader(prog);
GLint success = 0;
glGetShaderiv(prog, GL_COMPILE_STATUS, &success);
GLint logSize = 0;
glGetShaderiv(prog, GL_INFO_LOG_LENGTH, &logSize);
GLchar* log = new char[8192];
glGetShaderInfoLog(prog, 8192, 0, log);
cout << "manual compile " << success << endl << log << endl;
delete[] log;
}
glClearColor(1,1,0,1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
mContext->swapBuffers(this);
frame++;
}
Elsewhere, I have tested using QGLWidget, and on a project that uses GLEW instead of QOpenGLFunctions with exactly the same results.
The version of Qt I'm linking against was built with the following configuration:
configure -developer-build -opensource -nomake examples -nomake tests -mp -opengl desktop -icu -confirm-license
Any suggestions? Or shall I just send this in as a bug report?
Update
In response to peppe's comments:
1) What does QOpenGLDebugLogger says?
The only thing I can get from QOpenGLDebugLogger is
QWindowsGLContext::getProcAddress: Unable to resolve 'glGetPointerv'
This is printed when I initialize it (and not as a debug event firing, but just to console). It happens even though mContext->hasExtension(QByteArrayLiteral("GL_KHR_debug")) returns true and I'm initializing it within the first frame's draw() function.
2) Can you print the compile log of the QOGLShaders even if they compile successfully?
I cannot successfully compile QOpenGLShader or QGLShader at any point so I'm not able to test this. However, when compiling successfully using plain GL functions, the log returns blank.
3) Which GL version did you get from the context? (Check with QSurfaceFormat).
I've tried with versions 3.0, 3.2, 4.2, all with the same result.
4) Please set the same QSurfaceFormat on both the context and the window before creating them
5) Remember to create() the window
I've implemented both of these now and the result is the same.
I've just tested on a third PC and that has no issues. So it is this specific computer which, incidentally, happens to be a Mac Pro running Windows in bootcamp. It has had absolutely no trouble in any other context running the latest ATI drivers but I can only really conclude that there is a bug somewhere between the ATI drivers, this computer's graphics chip and QOpenGLShaderProgram.
I think I'm unlikely to find a solution, so giving up. Thank you for all your input!

C++ OpenGL GLEW Static Library on Windows 7 MSVC2012

I am attempting to Compile a simple OpenGL program on windows with statically linked glew32mxsd.lib... I am also working with glfw and if I compile without glew everything works.
I Downloaded the glew src and build the static mx debug library from source. I then copied the resulting glew32mxsd.lib file to my project directory. I am using cmake so my cmake code appears as follows.
SET (GLEW_VERSION 1.9.0)
SET (GLEW_DIRECTORY ${EXTERNAL_LIBS}/glew/${GLEW_VERSION})
SET (GLEW_INCLUDES ${GLEW_DIRECTORY}/include)
SET (GLEW_LIBS ${GLEW_DIRECTORY}/win/${SYSTEM_ARC}/lib)
INCLUDE_DIRECTORIES (${GLEW_INCLUDES})
ADD_EXECUTABLE (myproject ${HEADER_FILES} ${SOURCE_FILES})
TARGET_LINK_LIBRARIES(engine OpenGL32.lib)
TARGET_LINK_LIBRARIES(engine ${GLEW_LIBS}/glew32mxsd.lib)
Also in my source I am using the following in my header
#define GLEW_STATIC
#define GLEW_MX
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#ifdef WIN32
#include <GL/wglew.h>
#endif
//-----------------------------------------------------------------
static GLEWContext *glewGetContext()
{
return nullptr;
}
Everything compiles and links without any errors but...
When I run the program I get a memory access error. The call stack is
engine.exe!glewContextInit(GLEWContextStruct * ctx) Line 8912 C
engine.exe!cext::graphics::internal::WindowManager::initGLExtentions() Line 204 C++
engine.exe!cext::graphics::WindowManager::initGLExtentions() Line 273 C++
engine.exe!main(int argc, char * * argv) Line 363 C++
engine.exe!__tmainCRTStartup() Line 536 C
engine.exe!mainCRTStartup() Line 377 C
And looking at line 8912 in glew.c the following line is revealed
CONST_CAST(GLEW_VERSION_4_3) = ( major > 4 ) || ( major == 4 && minor >= 3 ) ? GL_TRUE : GL_FALSE;
My glewInit looks like the following
void initGLExtentions()
{
glewExperimental = true;
GLenum err = glewInit();
if (GLEW_OK != err)
{
printf("Error: %s\n",glewGetErrorString(err));
}
printf("Status: Using GLEW %s\n",glewGetString(GLEW_VERSION));
if (!GLEW_ARB_vertex_buffer_object)
{
printf("VBO not supported\n");
exit(EXIT_FAILURE);
}
}
...
glfwWindow *window = makeWindow(options,hints);
if (!window)
{
fprintf( stderr, "Failed to open GLFW window\n" );
glfwTerminate();
exit( EXIT_FAILURE );
}
glfwMakeContextCurrent(window);
initGLExtentions();
Using the same code on Mac works without a problem which leads me to believe that it is something to do with the static lib. However even after following all the instructions on the glew website I must be missing something still.
Edit: Additional Information
I ran dependency walker on my application after reading about it in another thread. Running dependency walker on my exe file produces the following missing files
API-MS-WIN-CORE-COM-L1-1-0.DLL
API-MS-WIN-CORE-WINRT-ERROR-L1-1-0.DLL
API-MS-WIN-CORE-WINRT-L1-1-0.DLL
API-MS-WIN-CORE-WINRT-ROBUFFER-L1-1-0.DLL
API-MS-WIN-CORE-WINRT-STRING-L1-1-0.DLL
API-MS-WIN-SHCORE-SCALING-L1-1-0.DLL
DCOMP.DLL
GPSVC.DLL
IESHIMS.DLL
These are called from the USER32.DLL. Are these related to the glew.lib or wglew.lib in anyway?