ifstream failing to open files in XCode even with full path[SOLVED] - c++

I am trying to get my C++ driven OpenGL working in a Cocoa app. In order to have everything in one place I need to load my shader and textures files in my C++. I'm doing that with std::ifstream, which fails to open files for some reason.
I have had a similar problem in the past when in order for XCode to open files you need to add them to the project and then do one of 3 things:
1) Copy them to Products Directory on the build phase
2) Change your Working directory in your scheme
3) Just use the full file path
However in my recent project neither have helped. The most interesting thing is in a very similar project(basically the project where I tried and tested everything it did work). I suppose I didn't move all the project settings over, but everything seems the same.
The only difference between them is that the one I'm working on now has more Objective-C in it.
#import <Cocoa/Cocoa.h>
#import <QuartzCore/CVDisplayLink.h>
#import "Application.hpp"
#interface viewObj : NSOpenGLView {
CVDisplayLinkRef displayLink;
Application* appInstance;
}
#end
#implementation viewObj
-(void)awakeFromNib
{
appInstance = new Application();
// other GL initializing code
}
#end
Application.hpp
#include "appView.hpp"
class Application {
private:
appView viewInstance{};
public:
Application();
void update();
~ Application();
};
appView.hpp
class appView {
private:
bool graphical;
GLuint texture;
int screenWidth, screenHeight;
Shader shader{"full_path/core.vs", "full_path/core.frag"};
std::vector<GLfloat> vert;
}
Shader.hpp
class Shader {
public:
GLuint Program;
Shader(const std::string& vertexPath, const std::string& fragmentPath)
{
std::string vertexCode;
std::string fragmentCode;
std::ifstream vShaderFile;
std::ifstream fShaderFile;
vShaderFile.exceptions (std::ifstream::badbit);
fShaderFile.exceptions (std::ifstream::badbit);
try
{
vShaderFile.open(vertexPath.c_str(), std::ios::in);// Failing here
if (!vShaderFile.is_open()) {
throw std::runtime_error(std::string("Failed to open shader file: ") + std::string(vertexPath));
}
fShaderFile.open(fragmentPath.c_str(), std::ios::in);
if (!fShaderFile.is_open()) {
throw std::runtime_error(std::string("Failed to open shader file: ") + std::string(fragmentPath));
}
std::stringstream vShaderStream, fShaderStream;
vShaderStream << vShaderFile.rdbuf();
vShaderStream << "\0";
fShaderStream << fShaderFile.rdbuf();
fShaderStream << "\0";
vShaderFile.close();
fShaderFile.close();
vertexCode = vShaderStream.str( );
fragmentCode = fShaderStream.str( );
}
catch ( std::ifstream::failure e )
{
std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl;
}
const GLchar *vShaderCode = (const GLchar *)vertexCode.c_str();
const GLchar *fShaderCode = (const GLchar *)fragmentCode.c_str();
// Compile shaders
GLuint vertex, fragment;
GLint success;
GLchar infoLog[512];
// Vertex Shader
vertex = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex, 1, &vShaderCode, NULL);
glCompileShader(vertex);
glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(vertex, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
}
// Fragment Shader
fragment = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment, 1, &fShaderCode, NULL);
glCompileShader(fragment);
glGetShaderiv(fragment, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(fragment, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
}
// Shader Program
this->Program = glCreateProgram();
glAttachShader(this->Program, vertex);
glAttachShader(this->Program, fragment);
glLinkProgram(this->Program);
glGetProgramiv(this->Program, GL_LINK_STATUS, &success);
if (!success)
{
glGetProgramInfoLog(this->Program, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
}
glDeleteShader(vertex);
glDeleteShader(fragment);
}
// Uses the current shader
void Use() const {
glUseProgram(this->Program);
}
};
Apparently the problem was with my app not having access to any files due to sandbox mode, which I disabled in .entitlements and that fixed the problem

Related

glCreateShader(GL_VERTEX_SHADER); access violation executing location

I am trying to draw some text and while trying to create the shader program for the text I get an access violation executing location error from GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
start of main Function where problem is:
int main(int argc, char **argv) {
//GLTtext* text = gltCreateText();
//gltSetText(text, "ElectroCraft");
//GLFWwindow* window;
int width = 860, height = 490;
if (!glfwInit()) {
printf("failed to init glfw");
return -1;
}
glutInit(&argc, argv);
window = glfwCreateWindow(width, height, "ElectroCraft", NULL, NULL);
glfwMakeContextCurrent(window);
if (!window) {
printf("failed to start window");
glfwTerminate();
return -1;
}
/*if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}*/
//build and compile shader program
//-----------------------------------
//vertex shader
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
//check for shader compile errors
int success;
char infoLog[512];
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
}
//fragment shader
int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
//check for shader compile errors
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
}
// link shaders
int shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
//check for liunking errors
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
}
...
all Includes as this may be the problem as well:
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <GL/freeglut.h>
#include <map>
#include <GL/GL.h>
#include <stdio.h>
#include <string>
#include <glm\glm.hpp>
#include <iostream>
#include <ft2build.h>
//#include <glad.h>
#include FT_FREETYPE_H
using namespace std;
I could be getting this problem as i might not of provided the correct arguments or something else.
You have include glew but you hadn't initialized it.
Before accessing any GL functions, insert this code:
GLenum err = glewInit();
if (GLEW_OK != err)
{
/* Problem: glewInit failed, something is seriously wrong. */
std::cerr << "Error: " << glewGetErrorString(err) << std::endl;
...
}
std::cerr << "Status: Using GLEW " << glewGetString(GLEW_VERSION) << std::endl;
Reference: GLEW Basics

OpenGL shader program fails to validate but gives no error message

I'm working on my custom game engine, and thus far everything is working fine.
Until I stumbled upon a weird error.
When I try to validate my shader program it returns GL_FALSE, to ensure good debugging I check the log info for error messages when something fails, but this error doesn't have a info log message, I checked whether it reads the files correctly and there's no error there... So I'm kinda stuck, I've looked all over the internet without any success, I hope someone on here can help me out with this one.
Thanks in advance!
In the main function I create a new shader program with 2 shader files, a vertex shader and a fragment shader, both compile without any errors.
GLuint shaderProgram = glCreateProgram();
std::string vertexFile = FileUtils::read_file("shaders/basic.vert");
std::string fragmentFile = FileUtils::read_file("shaders/basic.frag");
const char* vertexSource = vertexFile.c_str();
const char* fragmentSource = fragmentFile.c_str();
GLuint vertex = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex, 1, &vertexSource, NULL);
glCompileShader(vertex);
GLint result;
glGetShaderiv(vertex, GL_COMPILE_STATUS, &result);
if (result != GL_TRUE)
{
GLint length;
glGetShaderiv(vertex, GL_INFO_LOG_LENGTH, &length);
std::vector<char> error(length);
glGetShaderInfoLog(vertex, length, &length, &error[0]);
std::cerr << "Failed to compile the vertex shader!" << std::endl;
std::cerr << &error[0] << std::endl;
glDeleteShader(vertex);
return -1;
}
glAttachShader(shaderProgram, vertex);
GLuint fragment = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(fragment, 1, &fragmentSource, NULL);
glCompileShader(fragment);
glGetShaderiv(fragment, GL_COMPILE_STATUS, &result);
if (result != GL_TRUE)
{
GLint length;
glGetShaderiv(fragment, GL_INFO_LOG_LENGTH, &length);
std::vector<char> error(length);
glGetShaderInfoLog(fragment , length, &length, &error[0]);
std::cerr << "Failed to compile the fragment shader!" << std::endl;
std::cerr << &error[0] << std::endl;
glDeleteShader(fragment);
return -1;
}
glAttachShader(shaderProgram, fragment);
glValidateProgram(shaderProgram);
glGetProgramiv(shaderProgram, GL_VALIDATE_STATUS, &result);
if (result != GL_TRUE)
{
GLint length;
glGetProgramiv(shaderProgram, GL_INFO_LOG_LENGTH, &length);
std::vector<char> error(length);
glGetProgramInfoLog(shaderProgram, length, &length, &error[0]);
std::cerr << "Failed to validate the shader program!" << std::endl;
std::cerr << &error[0] << std::endl;
glDeleteProgram(shaderProgram);
return -1;
}
glLinkProgram(shaderProgram);
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &result);
if (result != GL_TRUE)
{
GLint length;
glGetProgramiv(shaderProgram, GL_INFO_LOG_LENGTH, &length);
std::vector<char> error(length);
glGetProgramInfoLog(shaderProgram, length, &length, &error[0]);
std::cerr << "Failed to link the shader program!" << std::endl;
std::cerr << &error[0] << std::endl;
glDeleteProgram(shaderProgram);
return -1;
}
glUseProgram(shaderProgram);
Here's the read_file function from my FileUtils class:
std::string FileUtils::read_file(const char* filepath)
{
FILE* file = fopen(filepath, "rt");
fseek(file, 0, SEEK_END);
unsigned long length = ftell(file);
char data[length + 1];
memset(data, 0, length + 1);
fseek(file, 0, SEEK_SET);
fread(data, 1, length, file);
fclose(file);
std::string result(data);
return result;
}
I know it loads the files correctly because I made them print to the console to make sure the paths and files were correct, no errors there!
P.S.
If you see any errors in the code (such as "shader" as variable name) that is because I had to edit the original code to make it all fit in 1 code block for this.
glValidateProgram should be placed after glLinkProgram, but before glUseProgram.
A quote from here:
glValidateProgram checks to see whether the executables contained in
program can execute given the current OpenGL state
If the program is not linked yet, it cannot be executed.

Returning std::string from method non-deterministic behavior?

I have a method that reads a file and returns its contents as a std::string. I use the returned std::string to compile an OpenGL program. The linking fails (Compiled vertex shader was corrupt.) in some cases due to one or both of the shader parts (read file contents) being NULL.
If I debug my code step by step everything is fine.
If I print the file contents the linking seems to fail less often.
Why is it behaving differently, where's my mistake?
The cout at the end always prints the correct file contents:
std::string read_file(const char* filePath) {
std::string content;
std::ifstream stream(filePath, std::ios::in);
if (stream.is_open()) {
std::string line = "";
while(getline(stream, line)) {
content += "\n" + line;
}
}
std::cout << "read_file " << content << "end read_file" << std::endl; // always prints the correct content
return content; // makes a copy, don't like that, unless RVO?..
}
The fragmentSource and or the vertextSource are sometimes empty:
GLuint fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
GLuint vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
const char* fragmentSource = tools::read_file(_fragmentShaderPath).c_str();
std::cout << "vertext shader source: " << std::endl << fragmentSource; // empty sometimes
glShaderSource(fragmentShaderID, 1, &fragmentSource, NULL);
glCompileShader(fragmentShaderID);
CheckCompilation(fragmentShaderID);
const char* vertexSource = tools::read_file(_vertexShaderPath).c_str();
std::cout << "vertext shader source: " << std::endl << vertexSource; // empty sometimes
glShaderSource(vertexShaderID, 1, &vertexSource, NULL);
glCompileShader(vertexShaderID);
CheckCompilation(vertexShaderID);
GLuint programId = glCreateProgram();
glAttachShader(programId, fragmentShaderID);
glAttachShader(programId, vertexShaderID);
glLinkProgram(programId);
GLint result = GL_FALSE;
GLint infoLogLength;
glGetProgramiv(programId, GL_LINK_STATUS, &result);
glGetProgramiv(programId, GL_INFO_LOG_LENGTH, &infoLogLength);
if (infoLogLength > 0) { // this fails sometimes, corresponding to either vertexSource or fragmentSource being empty
std::vector<char> infoLog(infoLogLength + 1);
glGetProgramInfoLog(programId, infoLogLength, NULL, &infoLog[0]);
std::cout << &infoLog[0] << std::endl;
}
Replace
const char* fragmentSource = tools::read_file(_fragmentShaderPath).c_str();
with
std::string fragmentSourceStr = tools::read_file(_fragmentShaderPath);
const char* fragmentSource = fragmentSourceStr.c_str();
and the same thing for the vertexSource.
The issue is that the string you return is a temporary, so it is destroyed after you initialize fragmentSource with a pointer to its data, which makes fragmentSource point to an already destructed storage.
If it were me, I'd prefer to deal only in c++ types until we actually touch the openGL C api.
So first I'd create a lightweight proxy function in the tools namespace:
namespace tools {
auto shaderSource(GLuint shaderId, const std::string& source)
{
auto ptr = std::addressof(source[0]);
return glShaderSource(shaderId, 1, std::addressof(ptr), nullptr);
}
}
Then replace the use of the raw pointer altogether:
auto fragmentSource = tools::read_file(_fragmentShaderPath);
std::cout << "vertext shader source: " << std::endl << fragmentSource; // empty sometimes
tools::shaderSource(fragmentShaderID, fragmentSource);

'std::basic_string<char,std::char_traits<char>,std::allocator<char>>::c_str': non-standard syntax; use '&' to create a pointer to member

I'm trying to make a function that can read and compile opengl vertex and fragment shader files, but I'm getting this error:
'std::basic_string<char,std::char_traits<char>,std::allocator<char>>::c_str': non-standard syntax; use '&' to create a pointer to member
I'm not quite sure how to fix it. Here is my code:
GLuint shader_load(const GLchar* vertex, const GLchar* fragment) {
std::string ver = file_read_all(vertex);
std::string frag = file_read_all(fragment);
const GLchar* verCode = ver.c_str;
const GLchar* fragCode = frag.c_str;
GLuint program;
GLuint verShader, fragShader;
GLint success;
GLchar log[512];
verShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(verShader, 1, &verCode, NULL);
glCompileShader(verShader);
glGetShaderiv(verShader, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(verShader, 512, NULL, log);
std::cout << "Failed to compile Vertex Shader\n" << log << std::endl;
return NULL;
}
fragShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragShader, 1, &fragCode, NULL);
glCompileShader(fragShader);
glGetShaderiv(fragShader, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(fragShader, 512, NULL, log);
std::cout << "Failed to compile Fragment Shader\n" << log << std::endl;
return NULL;
}
program = glCreateProgram();
glAttachShader(program, verShader);
glAttachShader(program, fragShader);
glLinkProgram(program);
glGetProgramiv(program, GL_LINK_STATUS, &success);
if (!success)
{
glGetProgramInfoLog(program, 512, NULL, log);
std::cout << "Failed to Link Shader\n" << log << std::endl;
}
glDeleteShader(verShader);
glDeleteShader(fragShader);
}
I'm using Visual Studio Community 2015 on Windows 10
std::string::c_str is a member function, if you want to call it, you should add ().
const GLchar* verCode = ver.c_str();
~~

Shader Attachment errors. Either invalid Program or shader

I was working on my graphics program. I am trying to abstract features from the Shaders into a class. I tested the regular drawing Code and it works. The shaders run as well but as soon as I start using these OpenGL shader functions it stops working.
Shader::Shader(char c)
{
//program = int(0);
if (program!=0 || glIsProgram(program))
glDeleteProgram(program);
uniforms.clear();
program = glCreateProgram();
}
void Shader::compileProgram()
{
GLint Result = GL_FALSE;
int InfoLogLength;
glLinkProgram(program);
glValidateProgram( program);
glGetProgramiv(program, GL_LINK_STATUS, &Result);
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &InfoLogLength);
std::string ProgramErrorMessage = std::string();
ProgramErrorMessage.resize( glm::max(InfoLogLength, int(1)));
glGetProgramInfoLog(program, InfoLogLength, NULL, &ProgramErrorMessage[0]);
std::cout << ProgramErrorMessage.c_str() << std::endl;
}
void Shader::addToProgram( std::string File, GLenum type)
{
std::cout << glGetError() << std::endl;
GLuint shader = glCreateShader(type);
std::cout << glewGetErrorString(glGetError()) << std::endl;
std::string ShaderCode;
std::ifstream ShaderStream(File, std::ios::in);
if(ShaderStream.is_open())
{
std::string Line = "";
while(getline(ShaderStream, Line))
ShaderCode += Line + "\n";
ShaderStream.close();
}
GLint Result = GL_FALSE;
int InfoLogLength;
// Compile Vertex Shader
std::cout << "Compiling shader : " << File<< std::endl;
const char * SourcePointer = ShaderCode.c_str();
std::cout << SourcePointer << std::endl;
int length = ShaderCode.size();
glShaderSource(shader, 1, &SourcePointer , &length );
glCompileShader(shader);
// Check Vertex Shader
glGetShaderiv(shader, GL_COMPILE_STATUS, &Result);
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &InfoLogLength);
std::vector<char> ShaderErrorMessage(InfoLogLength);
glGetShaderInfoLog(shader, InfoLogLength, NULL, &ShaderErrorMessage[0]);
printf("%s\n", &ShaderErrorMessage[0]);
glAttachShader(program, shader); //Invalid Operation, eighter Program or shader invalid
std::cout << glGetError() << std::endl;
}
So the Problem was that the Program was invalid.
What I did is this:
if(!glIsProgram(program))
program = glCreateProgram();
glAttachShaders(program, shader);
I did the same guard in the constructor. I am still wondering how that happened. I mean I checked the values in Debug and they all seemed valid.