Hi!
I made some tests and the problem is in the shader class.
Everything draws well with the shader class of the tutorial.
So it doesn't work with this code.
#include "application.h"
#include <SFML/OpenGL.hpp>
#include <SFML/Window/WindowStyle.hpp>
#include <stdio.h>
#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
#include <stddef.h>
#include <vector>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
/*using namespace odfaeg::core;
using namespace odfaeg::math;
using namespace odfaeg::physic;
using namespace odfaeg::graphic;
using namespace odfaeg::window;
using namespace odfaeg::audio;
using namespace sorrok;*/
using namespace std;
class Shader
{
public:
unsigned int ID;
// constructor generates the shader on the fly
// ------------------------------------------------------------------------
Shader(std::string vertexCode, std::string fragmentCode)
{
// 1. retrieve the vertex/fragment source code from filePath
const char* vShaderCode = vertexCode.c_str();
const char * fShaderCode = fragmentCode.c_str();
// 2. compile shaders
unsigned int vertex, fragment;
// vertex shader
vertex = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex, 1, &vShaderCode, NULL);
glCompileShader(vertex);
checkCompileErrors(vertex, "VERTEX");
// fragment Shader
fragment = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment, 1, &fShaderCode, NULL);
glCompileShader(fragment);
checkCompileErrors(fragment, "FRAGMENT");
// shader Program
ID = glCreateProgram();
glAttachShader(ID, vertex);
glAttachShader(ID, fragment);
glLinkProgram(ID);
checkCompileErrors(ID, "PROGRAM");
// delete the shaders as they're linked into our program now and no longer necessery
glDeleteShader(vertex);
glDeleteShader(fragment);
}
// activate the shader
// ------------------------------------------------------------------------
void use()
{
glUseProgram(ID);
}
// utility uniform functions
// ------------------------------------------------------------------------
void setBool(const std::string &name, bool value) const
{
glUniform1i(glGetUniformLocation(ID, name.c_str()), (int)value);
}
// ------------------------------------------------------------------------
void setInt(const std::string &name, int value) const
{
glUniform1i(glGetUniformLocation(ID, name.c_str()), value);
}
// ------------------------------------------------------------------------
void setFloat(const std::string &name, float value) const
{
glUniform1f(glGetUniformLocation(ID, name.c_str()), value);
}
// ------------------------------------------------------------------------
void setVec2(const std::string &name, const glm::vec2 &value) const
{
glUniform2fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);
}
void setVec2(const std::string &name, float x, float y) const
{
glUniform2f(glGetUniformLocation(ID, name.c_str()), x, y);
}
// ------------------------------------------------------------------------
void setVec3(const std::string &name, const glm::vec3 &value) const
{
glUniform3fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);
}
void setVec3(const std::string &name, float x, float y, float z) const
{
glUniform3f(glGetUniformLocation(ID, name.c_str()), x, y, z);
}
// ------------------------------------------------------------------------
void setVec4(const std::string &name, const glm::vec4 &value) const
{
glUniform4fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);
}
void setVec4(const std::string &name, float x, float y, float z, float w)
{
glUniform4f(glGetUniformLocation(ID, name.c_str()), x, y, z, w);
}
// ------------------------------------------------------------------------
void setMat2(const std::string &name, const glm::mat2 &mat) const
{
glUniformMatrix2fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
}
// ------------------------------------------------------------------------
void setMat3(const std::string &name, const glm::mat3 &mat) const
{
glUniformMatrix3fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
}
// ------------------------------------------------------------------------
void setMat4(const std::string &name, const glm::mat4 &mat) const
{
glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
}
private:
// utility function for checking shader compilation/linking errors.
// ------------------------------------------------------------------------
void checkCompileErrors(GLuint shader, std::string type)
{
GLint success;
GLchar infoLog[1024];
if(type != "PROGRAM")
{
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
if(!success)
{
glGetShaderInfoLog(shader, 1024, NULL, infoLog);
std::cout << "ERROR::SHADER_COMPILATION_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl;
}
}
else
{
glGetProgramiv(shader, GL_LINK_STATUS, &success);
if(!success)
{
glGetProgramInfoLog(shader, 1024, NULL, infoLog);
std::cout << "ERROR::PROGRAM_LINKING_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl;
}
}
}
};
// Defines several possible options for camera movement. Used as abstraction to stay away from window-system specific input methods
enum Camera_Movement {
FORWARD,
BACKWARD,
LEFT,
RIGHT
};
// Default camera values
const float YAW = -90.0f;
const float PITCH = 0.0f;
const float SPEED = 2.5f;
const float SENSITIVITY = 0.1f;
const float ZOOM = 45.0f;
// An abstract camera class that processes input and calculates the corresponding Euler Angles, Vectors and Matrices for use in OpenGL
class Camera
{
public:
// camera Attributes
glm::vec3 Position;
glm::vec3 Front;
glm::vec3 Up;
glm::vec3 Right;
glm::vec3 WorldUp;
// euler Angles
float Yaw;
float Pitch;
// camera options
float MovementSpeed;
float MouseSensitivity;
float Zoom;
// constructor with vectors
Camera(glm::vec3 position = glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f), float yaw = YAW, float pitch = PITCH) : Front(glm::vec3(0.0f, 0.0f, -1.0f)), MovementSpeed(SPEED), MouseSensitivity(SENSITIVITY), Zoom(ZOOM)
{
Position = position;
WorldUp = up;
Yaw = yaw;
Pitch = pitch;
updateCameraVectors();
}
// constructor with scalar values
Camera(float posX, float posY, float posZ, float upX, float upY, float upZ, float yaw, float pitch) : Front(glm::vec3(0.0f, 0.0f, -1.0f)), MovementSpeed(SPEED), MouseSensitivity(SENSITIVITY), Zoom(ZOOM)
{
Position = glm::vec3(posX, posY, posZ);
WorldUp = glm::vec3(upX, upY, upZ);
Yaw = yaw;
Pitch = pitch;
updateCameraVectors();
}
// returns the view matrix calculated using Euler Angles and the LookAt Matrix
glm::mat4 GetViewMatrix()
{
return glm::lookAt(Position, Position + Front, Up);
}
// processes input received from any keyboard-like input system. Accepts input parameter in the form of camera defined ENUM (to abstract it from windowing systems)
void ProcessKeyboard(Camera_Movement direction, float deltaTime)
{
float velocity = MovementSpeed * deltaTime;
if (direction == FORWARD)
Position += Front * velocity;
if (direction == BACKWARD)
Position -= Front * velocity;
if (direction == LEFT)
Position -= Right * velocity;
if (direction == RIGHT)
Position += Right * velocity;
}
// processes input received from a mouse input system. Expects the offset value in both the x and y direction.
void ProcessMouseMovement(float xoffset, float yoffset, GLboolean constrainPitch = true)
{
xoffset *= MouseSensitivity;
yoffset *= MouseSensitivity;
Yaw += xoffset;
Pitch += yoffset;
// make sure that when pitch is out of bounds, screen doesn't get flipped
if (constrainPitch)
{
if (Pitch > 89.0f)
Pitch = 89.0f;
if (Pitch < -89.0f)
Pitch = -89.0f;
}
// update Front, Right and Up Vectors using the updated Euler angles
updateCameraVectors();
}
// processes input received from a mouse scroll-wheel event. Only requires input on the vertical wheel-axis
void ProcessMouseScroll(float yoffset)
{
Zoom -= (float)yoffset;
if (Zoom < 1.0f)
Zoom = 1.0f;
if (Zoom > 45.0f)
Zoom = 45.0f;
}
private:
// calculates the front vector from the Camera's (updated) Euler Angles
void updateCameraVectors()
{
// calculate the new Front vector
glm::vec3 front;
front.x = cos(glm::radians(Yaw)) * cos(glm::radians(Pitch));
front.y = sin(glm::radians(Pitch));
front.z = sin(glm::radians(Yaw)) * cos(glm::radians(Pitch));
Front = glm::normalize(front);
// also re-calculate the Right and Up vector
Right = glm::normalize(glm::cross(Front, WorldUp)); // normalize the vectors, because their length gets closer to 0 the more you look up or down which results in slower movement.
Up = glm::normalize(glm::cross(Right, Front));
}
};
unsigned int loadCubemap(vector<std::string> faces);
// settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;
// camera
Camera camera(glm::vec3(0.0f, 0.0f, 3.0f));
float lastX = (float)SCR_WIDTH / 2.0;
float lastY = (float)SCR_HEIGHT / 2.0;
bool firstMouse = true;
// timing
float deltaTime = 0.0f;
float lastFrame = 0.0f;
int main(int argc, char* argv[])
{
/*EXPORT_CLASS_GUID(BoundingVolumeBoundingBox, BoundingVolume, BoundingBox)
EXPORT_CLASS_GUID(EntityTile, Entity, Tile)
EXPORT_CLASS_GUID(EntityTile, Entity, BigTile)
EXPORT_CLASS_GUID(EntityWall, Entity, g2d::Wall)
EXPORT_CLASS_GUID(EntityDecor, Entity, g2d::Decor)
EXPORT_CLASS_GUID(EntityAnimation, Entity, Anim)
EXPORT_CLASS_GUID(EntityHero, Entity, Hero)
EXPORT_CLASS_GUID(EntityMesh, Entity, Mesh)
MyAppli app(sf::VideoMode(800, 600), "Test odfaeg");
return app.exec();*/
// create the window
sf::Window window(sf::VideoMode(800, 600), "OpenGL", sf::Style::Default, sf::ContextSettings(32, 0, 4, 3, 3));
glewInit();
window.setVerticalSyncEnabled(true);
// activate the window
window.setActive(true);
// load resources, initialize the OpenGL states, ...
glEnable(GL_DEPTH_TEST);
// build and compile shaders
// -------------------------
const std::string cubeMapsVS = R"(#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
out vec3 Normal;
out vec3 Position;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
Normal = mat3(transpose(inverse(model))) * aNormal;
Position = vec3(model * vec4(aPos, 1.0));
gl_Position = projection * view * model * vec4(aPos, 1.0);
}
)";
const std::string cubeMapsFS = R"(#version 330 core
out vec4 FragColor;
in vec3 Normal;
in vec3 Position;
uniform vec3 cameraPos;
uniform samplerCube skybox;
void main()
{
vec3 I = normalize(Position - cameraPos);
vec3 R = reflect(I, normalize(Normal));
FragColor = vec4(texture(skybox, R).rgb, 1.0);
}
)";
const std::string skyboxVS = R"(#version 330 core
layout (location = 0) in vec3 aPos;
out vec3 TexCoords;
uniform mat4 projection;
uniform mat4 view;
void main()
{
TexCoords = aPos;
vec4 pos = projection * view * vec4(aPos, 1.0);
gl_Position = pos.xyww;
}
)";
const std::string skyboxFS = R"(#version 330 core
out vec4 FragColor;
in vec3 TexCoords;
uniform samplerCube skybox;
void main()
{
FragColor = texture(skybox, TexCoords);
}
)";
odfaeg::graphic::Shader shader, skyboxShader;
shader.loadFromMemory(cubeMapsVS, cubeMapsFS);
skyboxShader.loadFromMemory(skyboxFS, skyboxVS);
// set up vertex data (and buffer(s)) and configure vertex attributes
// ------------------------------------------------------------------
float cubeVertices[] = {
// positions // normals
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f
};
float skyboxVertices[] = {
// positions
-1.0f, 1.0f, -1.0f,
-1.0f, -1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
1.0f, 1.0f, -1.0f,
-1.0f, 1.0f, -1.0f,
-1.0f, -1.0f, 1.0f,
-1.0f, -1.0f, -1.0f,
-1.0f, 1.0f, -1.0f,
-1.0f, 1.0f, -1.0f,
-1.0f, 1.0f, 1.0f,
-1.0f, -1.0f, 1.0f,
1.0f, -1.0f, -1.0f,
1.0f, -1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, 1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, -1.0f, 1.0f,
-1.0f, -1.0f, 1.0f,
-1.0f, 1.0f, -1.0f,
1.0f, 1.0f, -1.0f,
1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, -1.0f,
-1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, 1.0f,
1.0f, -1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, 1.0f,
1.0f, -1.0f, 1.0f
};
// cube VAO
unsigned int cubeVAO, cubeVBO;
glGenVertexArrays(1, &cubeVAO);
glGenBuffers(1, &cubeVBO);
glBindVertexArray(cubeVAO);
glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertices), &cubeVertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));
// skybox VAO
unsigned int skyboxVAO, skyboxVBO;
glGenVertexArrays(1, &skyboxVAO);
glGenBuffers(1, &skyboxVBO);
glBindVertexArray(skyboxVAO);
glBindBuffer(GL_ARRAY_BUFFER, skyboxVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(skyboxVertices), &skyboxVertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
// load textures
// -------------
vector<std::string> faces
{
"tilesets/skybox/right.jpg",
"tilesets/skybox/left.jpg",
"tilesets/skybox/top.jpg",
"tilesets/skybox/bottom.jpg",
"tilesets/skybox/front.jpg",
"tilesets/skybox/back.jpg"
};
unsigned int cubemapTexture = loadCubemap(faces);
glEnable(GL_TEXTURE_CUBE_MAP);
// shader configuration
// --------------------
odfaeg::graphic::Shader::bind(&shader);
unsigned int index = 0;
shader.setParameter("skybox", index);
odfaeg::graphic::Shader::bind(&skyboxShader);
skyboxShader.setParameter("skybox", index);
int oldX = sf::Mouse::getPosition(window).x;
int oldY = sf::Mouse::getPosition(window).y;
sf::Clock time;
// run the main loop
bool running = true;
while (running)
{
// per-frame time logic
// --------------------
// per-frame time logic
// --------------------
float currentFrame = time.getElapsedTime().asSeconds();
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;
// handle events
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
{
// end the program
running = false;
}
else if (event.type == sf::Event::Resized)
{
// adjust the viewport when the window is resized
glViewport(0, 0, event.size.width, event.size.height);
}
else if (event.type == sf::Event::MouseMoved) {
if (firstMouse)
{
lastX = event.mouseMove.x;
lastY = event.mouseMove.y;
firstMouse = false;
}
float xoffset = event.mouseMove.x - lastX;
float yoffset = lastY - event.mouseMove.y; // reversed since y-coordinates go from bottom to top
lastX = event.mouseMove.x;
lastY = event.mouseMove.y;
camera.ProcessMouseMovement(xoffset, yoffset);
} else if (event.type == sf::Event::MouseWheelScrolled) {
camera.ProcessMouseScroll(event.mouseWheelScroll.delta);
}
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) {
camera.ProcessKeyboard(FORWARD, deltaTime);
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) {
camera.ProcessKeyboard(BACKWARD, deltaTime);
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) {
camera.ProcessKeyboard(RIGHT, deltaTime);
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) {
camera.ProcessKeyboard(LEFT, deltaTime);
}
// clear the buffers
// render
// ------
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// draw...
odfaeg::graphic::Shader::bind(&shader);
glm::mat4 model = glm::mat4(1.0f);
glm::mat4 view = camera.GetViewMatrix();
glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
odfaeg::math::Matrix4f modelMatrix(model[0][0],model[0][1],model[0][2],model[0][3],
model[1][0],model[1][1],model[1][2],model[1][3],
model[2][0],model[2][1],model[2][2],model[2][3],
model[3][0],model[3][1],model[3][2],model[3][3]);
odfaeg::math::Matrix4f viewMatrix(view[0][0],view[0][1],view[0][2],view[0][3],
view[1][0],view[1][1],view[1][2],view[1][3],
view[2][0],view[2][1],view[2][2],view[2][3],
view[3][0],view[3][1],view[3][2],view[3][3]);
odfaeg::math::Matrix4f projectionMatrix(projection[0][0],projection[0][1],projection[0][2],projection[0][3],
projection[1][0],projection[1][1],projection[1][2],projection[1][3],
projection[2][0],projection[2][1],projection[2][2],projection[2][3],
projection[3][0],projection[3][1],projection[3][2],projection[3][3]);
shader.setParameter("model", modelMatrix);
shader.setParameter("view", viewMatrix);
shader.setParameter("projection", projectionMatrix);
shader.setParameter("cameraPos", camera.Position.x,camera.Position.y,camera.Position.z);
// cubes
glBindVertexArray(cubeVAO);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture);
glDrawArrays(GL_TRIANGLES, 0, 36);
glBindVertexArray(0);
// draw skybox as last
glDepthFunc(GL_LEQUAL); // change depth function so depth test passes when values are equal to depth buffer's content
odfaeg::graphic::Shader::bind(&skyboxShader);
view = glm::mat4(glm::mat3(camera.GetViewMatrix())); // remove translation from the view matrix
viewMatrix = odfaeg::math::Matrix4f(view[0][0],view[0][1],view[0][2],view[0][3],
view[1][0],view[1][1],view[1][2],view[1][3],
view[2][0],view[2][1],view[2][2],view[2][3],
view[3][0],view[3][1],view[3][2],view[3][3]);
skyboxShader.setParameter("view", viewMatrix);
skyboxShader.setParameter("projection", projectionMatrix);
// skybox cube
glBindVertexArray(skyboxVAO);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture);
glDrawArrays(GL_TRIANGLES, 0, 36);
glBindVertexArray(0);
glDepthFunc(GL_LESS); // set depth function back to default
// end the current frame (internally swaps the front and back buffers)
window.display();
oldX = sf::Mouse::getPosition(window).x;
oldY = sf::Mouse::getPosition(window).y;
}
// optional: de-allocate all resources once they've outlived their purpose:
// ------------------------------------------------------------------------
glDeleteVertexArrays(1, &cubeVAO);
glDeleteVertexArrays(1, &skyboxVAO);
glDeleteBuffers(1, &cubeVBO);
glDeleteBuffers(1, &skyboxVAO);
// release resources...
return 0;
}
unsigned int loadCubemap(vector<std::string> faces)
{
unsigned int textureID;
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_CUBE_MAP, textureID);
int width, height;
for (unsigned int i = 0; i < faces.size(); i++)
{
sf::Image image;
image.loadFromFile(faces[i]);
width = image.getSize().x;
height = image.getSize().y;
if (image.getPixelsPtr())
{
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image.getPixelsPtr());
}
else
{
std::cout << "Cubemap texture failed to load at path: " << faces[i] << std::endl;
}
}
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
return textureID;
}
I guess I've to change the shader class with doesn't work, it's a copy of the shader class of the SFML.
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2013 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include "../../../include/odfaeg/Graphics/shader.h"
#include "../../../include/odfaeg/Graphics/texture.h"
#include "glCheck.h"
#include <SFML/System/InputStream.hpp>
#include <SFML/System/Err.hpp>
#include <fstream>
#include <vector>
#include <GL/glew.h>
#include <SFML/OpenGL.hpp>
using namespace sf;
namespace
{
// Retrieve the maximum number of texture units available
GLint getMaxTextureUnits()
{
GLint maxUnits;
glCheck(glGetIntegerv(GL_MAX_TEXTURE_COORDS_ARB, &maxUnits));
return maxUnits;
}
// Read the contents of a file into an array of char
bool getFileContents(const std::string& filename, std::vector<char>& buffer)
{
std::ifstream file(filename.c_str(), std::ios_base::binary);
if (file)
{
file.seekg(0, std::ios_base::end);
std::streamsize size = file.tellg();
if (size > 0)
{
file.seekg(0, std::ios_base::beg);
buffer.resize(static_cast<std::size_t>(size));
file.read(&buffer[0], size);
}
buffer.push_back('\0');
return true;
}
else
{
return false;
}
}
// Read the contents of a stream into an array of char
bool getStreamContents(sf::InputStream& stream, std::vector<char>& buffer)
{
bool success = true;
sf::Int64 size = stream.getSize();
if (size > 0)
{
buffer.resize(static_cast<std::size_t>(size));
stream.seek(0);
sf::Int64 read = stream.read(&buffer[0], size);
success = (read == size);
}
buffer.push_back('\0');
return success;
}
}
namespace odfaeg {
namespace graphic {
////////////////////////////////////////////////////////////
Shader::CurrentTextureType Shader::CurrentTexture;
unsigned int Shader::shading_language_version_major = 0;
unsigned int Shader::shading_language_version_minor = 0;
////////////////////////////////////////////////////////////
Shader::Shader() :
m_shaderProgram (0),
m_currentTexture(-1),
m_textures (),
m_params (),
m_vertexAttribs ()
{
shading_language_version_major = getVersionMajor();
shading_language_version_minor = getVersionMinor();
}
////////////////////////////////////////////////////////////
Shader::~Shader()
{
//ensureGlContext();
// Destroy effect program
if (m_shaderProgram) {
if (shading_language_version_major >= 3 && shading_language_version_minor >= 3)
glCheck(glDeleteProgram(m_shaderProgram));
else
glCheck(glDeleteObjectARB(m_shaderProgram));
}
}
////////////////////////////////////////////////////////////
bool Shader::loadFromFile(const std::string& filename, Type type)
{
// Read the file
std::vector<char> shader;
if (!getFileContents(filename, shader))
{
err() << "Failed to open shader file \"" << filename << "\"" << std::endl;
return false;
}
// Compile the shader program
if (type == Vertex)
return compile(&shader[0], NULL);
else
return compile(NULL, &shader[0]);
}
////////////////////////////////////////////////////////////
bool Shader::loadFromFile(const std::string& vertexShaderFilename, const std::string& fragmentShaderFilename)
{
// Read the vertex shader file
std::vector<char> vertexShader;
if (!getFileContents(vertexShaderFilename, vertexShader))
{
err() << "Failed to open vertex shader file \"" << vertexShaderFilename << "\"" << std::endl;
return false;
}
// Read the fragment shader file
std::vector<char> fragmentShader;
if (!getFileContents(fragmentShaderFilename, fragmentShader))
{
err() << "Failed to open fragment shader file \"" << fragmentShaderFilename << "\"" << std::endl;
return false;
}
// Compile the shader program
return compile(&vertexShader[0], &fragmentShader[0]);
}
////////////////////////////////////////////////////////////
bool Shader::loadFromMemory(const std::string& shader, Type type)
{
// Compile the shader program
if (type == Vertex)
return compile(shader.c_str(), NULL);
else
return compile(NULL, shader.c_str());
}
////////////////////////////////////////////////////////////
bool Shader::loadFromMemory(const std::string& vertexShader, const std::string& fragmentShader)
{
// Compile the shader program
return compile(vertexShader.c_str(), fragmentShader.c_str());
}
////////////////////////////////////////////////////////////
bool Shader::loadFromStream(InputStream& stream, Type type)
{
// Read the shader code from the stream
std::vector<char> shader;
if (!getStreamContents(stream, shader))
{
err() << "Failed to read shader from stream" << std::endl;
return false;
}
// Compile the shader program
if (type == Vertex)
return compile(&shader[0], NULL);
else
return compile(NULL, &shader[0]);
}
////////////////////////////////////////////////////////////
bool Shader::loadFromStream(InputStream& vertexShaderStream, InputStream& fragmentShaderStream)
{
// Read the vertex shader code from the stream
std::vector<char> vertexShader;
if (!getStreamContents(vertexShaderStream, vertexShader))
{
err() << "Failed to read vertex shader from stream" << std::endl;
return false;
}
// Read the fragment shader code from the stream
std::vector<char> fragmentShader;
if (!getStreamContents(fragmentShaderStream, fragmentShader))
{
err() << "Failed to read fragment shader from stream" << std::endl;
return false;
}
// Compile the shader program
return compile(&vertexShader[0], &fragmentShader[0]);
}
////////////////////////////////////////////////////////////
void Shader::setParameter(const std::string& name, unsigned int x)
{
if (m_shaderProgram)
{
if (shading_language_version_major >= 3 && shading_language_version_minor >= 3) {
glCheck(glUseProgram(m_shaderProgram));
GLint location = glGetUniformLocation(m_shaderProgram, name.c_str());
if (location != -1) {
glCheck(glUniform1ui(location, x));
}
} else {
// Enable program
GLhandleARB program = glGetHandleARB(GL_PROGRAM_OBJECT_ARB);
glCheck(glUseProgramObjectARB(m_shaderProgram));
// Get parameter location and assign it new values
GLint location = getParamLocation(name);
if (location != -1)
glCheck(glUniform1ui(location, x));
// Disable program
glCheck(glUseProgramObjectARB(program));
}
}
}
////////////////////////////////////////////////////////////
void Shader::setParameter(const std::string& name, float x)
{
if (m_shaderProgram)
{
if (shading_language_version_major >= 3 && shading_language_version_minor >= 3) {
glCheck(glUseProgram(m_shaderProgram));
GLint location = glGetUniformLocation(m_shaderProgram, name.c_str());
if (location != -1) {
glCheck(glUniform1f(location, x));
}
} else {
// Enable program
GLhandleARB program = glGetHandleARB(GL_PROGRAM_OBJECT_ARB);
glCheck(glUseProgramObjectARB(m_shaderProgram));
// Get parameter location and assign it new values
GLint location = getParamLocation(name);
if (location != -1)
glCheck(glUniform1fARB(location, x));
// Disable program
glCheck(glUseProgramObjectARB(program));
}
}
}
////////////////////////////////////////////////////////////
void Shader::setParameter(const std::string& name, float x, float y)
{
if (m_shaderProgram)
{
if (shading_language_version_major >= 3 && shading_language_version_minor >= 3) {
glCheck(glUseProgram(m_shaderProgram));
GLint location = glGetUniformLocation(m_shaderProgram, name.c_str());
if (location != -1) {
glCheck(glUniform2f(location, x, y));
}
} else {
// Enable program
GLhandleARB program = glGetHandleARB(GL_PROGRAM_OBJECT_ARB);
glCheck(glUseProgramObjectARB(m_shaderProgram));
// Get parameter location and assign it new values
GLint location = getParamLocation(name);
if (location != -1)
glCheck(glUniform2fARB(location, x, y));
// Disable program
glCheck(glUseProgramObjectARB(program));
}
}
}
////////////////////////////////////////////////////////////
void Shader::setParameter(const std::string& name, float x, float y, float z)
{
if (m_shaderProgram)
{
if (shading_language_version_major >= 3 && shading_language_version_minor >= 3) {
glCheck(glUseProgram(m_shaderProgram));
GLint location = glGetUniformLocation(m_shaderProgram, name.c_str());
if (location != -1) {
glCheck(glUniform3f(location, x, y, z));
}
} else {
// Enable program
GLhandleARB program = glGetHandleARB(GL_PROGRAM_OBJECT_ARB);
glCheck(glUseProgramObjectARB(m_shaderProgram));
// Get parameter location and assign it new values
GLint location = getParamLocation(name);
if (location != -1)
glCheck(glUniform3fARB(location, x, y, z));
// Disable program
glCheck(glUseProgramObjectARB(program));
}
}
}
////////////////////////////////////////////////////////////
void Shader::setParameter(const std::string& name, float x, float y, float z, float w)
{
if (m_shaderProgram)
{
if (shading_language_version_major >= 3 && shading_language_version_minor >= 3) {
glCheck(glUseProgram(m_shaderProgram));
GLint location = glGetUniformLocation(m_shaderProgram, name.c_str());
if (location != -1) {
glCheck(glUniform4f(location, x, y, z, w));
}
} else {
// Enable program
GLhandleARB program = glGetHandleARB(GL_PROGRAM_OBJECT_ARB);
glCheck(glUseProgramObjectARB(m_shaderProgram));
// Get parameter location and assign it new values
GLint location = getParamLocation(name);
if (location != -1)
glCheck(glUniform4fARB(location, x, y, z, w));
// Disable program
glCheck(glUseProgramObjectARB(program));
}
}
}
////////////////////////////////////////////////////////////
void Shader::setParameter(const std::string& name, const Vector2f& v)
{
setParameter(name, v.x, v.y);
}
////////////////////////////////////////////////////////////
void Shader::setParameter(const std::string& name, const Vector3f& v)
{
setParameter(name, v.x, v.y, v.z);
}
////////////////////////////////////////////////////////////
void Shader::setParameter(const std::string& name, const Color& color)
{
setParameter(name, color.r / 255.f, color.g / 255.f, color.b / 255.f, color.a / 255.f);
}
////////////////////////////////////////////////////////////
void Shader::setParameter(const std::string& name, math::Matrix4f matrix)
{
if (m_shaderProgram)
{
if (shading_language_version_major >= 3 && shading_language_version_minor >= 3) {
glCheck(glUseProgram(m_shaderProgram));
GLint location = getParamLocation(name);
if (location != -1) {
glCheck(glUniformMatrix4fv(location, 1, GL_FALSE,matrix.toGlMatrix().data()));
}
glCheck(glUseProgram(0));
} else {
// Enable program
GLhandleARB program = glGetHandleARB(GL_PROGRAM_OBJECT_ARB);
glCheck(glUseProgramObjectARB(m_shaderProgram));
// Get parameter location and assign it new values
GLint location = getParamLocation(name);
if (location != -1) {
std::array<float, 16> glmatrix = matrix.toGlMatrix();
glCheck(glUniformMatrix4fvARB(location, 1, GL_FALSE, glmatrix.data()));
}
// Disable program
glCheck(glUseProgramObjectARB(program));
}
}
}
////////////////////////////////////////////////////////////
void Shader::setParameter(const std::string& name, std::vector<TransformMatrix*> transforms)
{
if (m_shaderProgram)
{
/*if (shading_language_version_major >= 3 && shading_language_version_minor >= 3) {
glCheck(glUseProgram(m_shaderProgram));
GLint location = getParamLocation(name);
if (location != -1) {
glCheck(glUniformMatrix4fv(location, 1, GL_FALSE,matrix.toGlMatrix().data()));
}
glCheck(glUseProgram(0));
} else {*/
// Enable program
GLhandleARB program = glGetHandleARB(GL_PROGRAM_OBJECT_ARB);
glCheck(glUseProgramObjectARB(m_shaderProgram));
// Get parameter location and assign it new values
GLint location = getParamLocation(name);
if (location != -1) {
std::vector<float> matrices;
for (unsigned int i = 0; i < transforms.size(); i++) {
std::array<float, 16> glmatrix = transforms[i]->getMatrix().transpose().toGlMatrix();
for (unsigned int j = 0; j < glmatrix.size(); j++) {
matrices.push_back(glmatrix[j]);
}
}
glCheck(glUniformMatrix4fvARB(location, static_cast<GLsizei>(transforms.size()), GL_FALSE, &matrices[0]));
}
// Disable program
glCheck(glUseProgramObjectARB(program));
//}
}
}
////////////////////////////////////////////////////////////
void Shader::setParameter(const std::string& name, const Texture& texture)
{
if (m_shaderProgram)
{
// Find the location of the variable in the shader
int location = getParamLocation(name);
if (location != -1)
{
// Store the location -> texture mapping
TextureTable::iterator it = m_textures.find(location);
if (it == m_textures.end())
{
// New entry, make sure there are enough texture units
static const GLint maxUnits = getMaxTextureUnits();
if (m_textures.size() + 1 >= static_cast<std::size_t>(maxUnits))
{
err() << "Impossible to use texture \"" << name << "\" for shader: all available texture units are used" << std::endl;
return;
}
m_textures[location] = &texture;
}
else
{
// Location already used, just replace the texture
it->second = &texture;
}
}
}
}
void Shader::setParameter(const std::string& name) {
GLuint imageLoc = glGetUniformLocation(m_shaderProgram, name.c_str());
}
////////////////////////////////////////////////////////////
void Shader::bindAttribute(int location, const std::string& name) {
if (m_shaderProgram) {
GLint n;
glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &n);
if (location < n) {
if (shading_language_version_major >= 3 && shading_language_version_minor >= 3) {
glCheck(glBindAttribLocation(m_shaderProgram,location,name.c_str()));
} else {
glCheck(glBindAttribLocationARB(m_shaderProgram,location,name.c_str()));
}
m_currentAttrib = getVertexAttribLocation(name);
} else {
err() << "Invalid attribute location " << location << " in vertex." << std::endl;
}
}
}
////////////////////////////////////////////////////////////
void Shader::setParameter(const std::string& name, CurrentTextureType)
{
if (m_shaderProgram)
{
// Find the location of the variable in the shader
m_currentTexture = getParamLocation(name);
}
}
////////////////////////////////////////////////////////////
void Shader::bind(const Shader* shader)
{
if (shader && shader->m_shaderProgram)
{
if (shading_language_version_major >= 3 && shading_language_version_minor >= 3) {
glCheck(glUseProgram(shader->m_shaderProgram));
shader->bindTextures();
// Bind the current texture
if (shader->m_currentTexture != -1)
glCheck(glUniform1i(shader->m_currentTexture, 0));
} else {
// Enable the program
glCheck(glUseProgramObjectARB(shader->m_shaderProgram));
// Bind the textures
shader->bindTextures();
// Bind the current texture
if (shader->m_currentTexture != -1)
glCheck(glUniform1iARB(shader->m_currentTexture, 0));
}
}
else
{
if (shading_language_version_major >= 3 && shading_language_version_minor >= 3) {
glCheck(glUseProgram(0));
} else {
// Bind no shader
glCheck(glUseProgramObjectARB(0));
}
}
}
////////////////////////////////////////////////////////////
bool Shader::isAvailable()
{
// Make sure that GLEW is initialized
priv::ensureGlewInit();
/*if (shading_language_version_major >= 3 && shading_language_version_minor >= 3)
return true;*/
return true;
}
////////////////////////////////////////////////////////////
bool Shader::compile(const char* vertexShaderCode, const char* fragmentShaderCode)
{
// First make sure that we can use shaders
if (!isAvailable())
{
err() << "Failed to create a shader: your system doesn't support shaders "
<< "(you should test Shader::isAvailable() before trying to use the Shader class)" << std::endl;
return false;
}
// Destroy the shader if it was already created
if (m_shaderProgram) {
if (shading_language_version_major >= 3 && shading_language_version_minor >= 3)
glCheck(glDeleteProgram(m_shaderProgram));
else
glCheck(glDeleteObjectARB(m_shaderProgram));
}
// Reset the internal state
m_currentTexture = -1;
m_textures.clear();
m_params.clear();
// Create the program
if (shading_language_version_major >= 3 && shading_language_version_minor >= 3)
m_shaderProgram = glCreateProgram();
else
m_shaderProgram = glCreateProgramObjectARB();
// Create the vertex shader if needed
if (vertexShaderCode)
{
if (shading_language_version_major >= 3 && shading_language_version_minor >= 3) {
GLuint vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
glCheck(glShaderSource(vertexShaderID, 1, &vertexShaderCode, nullptr));
glCheck(glCompileShader(vertexShaderID));
GLint success;
glCheck(glGetShaderiv(vertexShaderID, GL_COMPILE_STATUS,&success));
if (success == GL_FALSE) {
int infoLogLength;
glCheck(glGetShaderiv(vertexShaderID, GL_INFO_LOG_LENGTH, &infoLogLength));
char log[infoLogLength];
glCheck(glGetShaderInfoLog(vertexShaderID, infoLogLength, 0, &log[0]));
std::cerr << "Failed to compile vertex shader:" << std::endl
<< log << std::endl;
glCheck(glDeleteShader(vertexShaderID));
glCheck(glDeleteProgram(m_shaderProgram));
m_shaderProgram = 0;
return false;
}
glCheck(glAttachShader(m_shaderProgram, vertexShaderID));
glCheck(glDeleteShader(vertexShaderID));
} else {
// Create and compile the shader
GLhandleARB vertexShader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
glCheck(glShaderSourceARB(vertexShader, 1, &vertexShaderCode, NULL));
glCheck(glCompileShaderARB(vertexShader));
// Check the compile log
GLint success;
glCheck(glGetObjectParameterivARB(vertexShader, GL_OBJECT_COMPILE_STATUS_ARB, &success));
if (success == GL_FALSE)
{
char log[1024];
glCheck(glGetInfoLogARB(vertexShader, sizeof(log), 0, log));
std::cerr << "Failed to compile vertex shader:" << std::endl
<< log << std::endl;
glCheck(glDeleteObjectARB(vertexShader));
glCheck(glDeleteObjectARB(m_shaderProgram));
m_shaderProgram = 0;
return false;
}
glCheck(glAttachObjectARB(m_shaderProgram, vertexShader));
glCheck(glDeleteObjectARB(vertexShader));
}
}
// Create the fragment shader if needed
if (fragmentShaderCode)
{
// Create and compile the shader
if (shading_language_version_major >= 3 && shading_language_version_minor >= 3) {
GLuint fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
glCheck(glShaderSource(fragmentShaderID, 1, &fragmentShaderCode, nullptr));
glCheck(glCompileShader(fragmentShaderID));
GLint success;
glCheck(glGetShaderiv(fragmentShaderID, GL_COMPILE_STATUS,&success));
if (success == GL_FALSE) {
int infoLogLength;
glCheck(glGetShaderiv(fragmentShaderID, GL_INFO_LOG_LENGTH, &infoLogLength));
char log[infoLogLength];
glCheck(glGetShaderInfoLog(fragmentShaderID, infoLogLength, 0, &log[0]));
std::cerr << "Failed to compile fragment shader:" << std::endl
<< log << std::endl;
glCheck(glDeleteShader(fragmentShaderID));
glCheck(glDeleteProgram(m_shaderProgram));
m_shaderProgram = 0;
return false;
}
glCheck(glAttachShader(m_shaderProgram, fragmentShaderID));
glCheck(glDeleteShader(fragmentShaderID));
} else {
GLhandleARB fragmentShader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
glCheck(glShaderSourceARB(fragmentShader, 1, &fragmentShaderCode, NULL));
glCheck(glCompileShaderARB(fragmentShader));
// Check the compile log
GLint success;
glCheck(glGetObjectParameterivARB(fragmentShader, GL_OBJECT_COMPILE_STATUS_ARB, &success));
if (success == GL_FALSE)
{
char log[1024];
glCheck(glGetInfoLogARB(fragmentShader, sizeof(log), 0, log));
std::cerr << "Failed to compile fragment shader:" << std::endl
<< log << std::endl;
glCheck(glDeleteObjectARB(fragmentShader));
glCheck(glDeleteObjectARB(m_shaderProgram));
m_shaderProgram = 0;
return false;
}
glCheck(glAttachObjectARB(m_shaderProgram, fragmentShader));
glCheck(glDeleteObjectARB(fragmentShader));
}
}
if (shading_language_version_major >= 3 && shading_language_version_minor >= 3) {
glCheck(glLinkProgram(m_shaderProgram));
GLint success;
glCheck(glGetProgramiv(m_shaderProgram, GL_LINK_STATUS, &success));
if (success == GL_FALSE) {
int infoLogLength;
glCheck(glGetProgramiv(m_shaderProgram, GL_INFO_LOG_LENGTH, &infoLogLength));
std::vector<char> programErrorMessage(std::max(infoLogLength, int(1)) );
glCheck(glGetProgramInfoLog(m_shaderProgram, infoLogLength, nullptr, &programErrorMessage[0]));
std::cerr << "Failed to link shader:" << std::endl
/* << log << std::endl*/;
glCheck(glDeleteProgram(m_shaderProgram));
m_shaderProgram = 0;
return false;
}
} else {
// Link the program
glCheck(glLinkProgramARB(m_shaderProgram));
// Check the link log
GLint success;
glCheck(glGetObjectParameterivARB(m_shaderProgram, GL_OBJECT_LINK_STATUS_ARB, &success));
if (success == GL_FALSE)
{
char log[1024];
glCheck(glGetInfoLogARB(m_shaderProgram, sizeof(log), 0, log));
err() << "Failed to link shader:" << std::endl
<< log << std::endl;
glCheck(glDeleteObjectARB(m_shaderProgram));
m_shaderProgram = 0;
return false;
}
}
// Force an OpenGL flush, so that the shader will appear updated
// in all contexts immediately (solves problems in multi-threaded apps)
glCheck(glFlush());
return true;
}
////////////////////////////////////////////////////////////
void Shader::bindTextures() const
{
TextureTable::const_iterator it = m_textures.begin();
for (std::size_t i = 0; i < m_textures.size(); ++i)
{
GLint index = static_cast<GLsizei>(i + 1);
if (shading_language_version_major >= 3 && shading_language_version_minor >= 3) {
glCheck(glUniform1i(it->first, index));
glCheck(glActiveTexture(GL_TEXTURE0 + index));
} else {
glCheck(glUniform1iARB(it->first, index));
glCheck(glActiveTextureARB(GL_TEXTURE0_ARB + index));
}
Texture::bind(it->second);
++it;
}
if (shading_language_version_major >= 3 && shading_language_version_minor >= 3) {
glCheck(glActiveTexture(GL_TEXTURE0));
} else {
// Make sure that the texture unit which is left active is the number 0
glCheck(glActiveTextureARB(GL_TEXTURE0_ARB));
}
}
int Shader::getVertexAttribLocation(const std::string& name) {
VertexAttribTable::const_iterator it = m_vertexAttribs.find(name);
if (it != m_vertexAttribs.end()) {
return it->second;
} else {
int location;
if (shading_language_version_major >= 3 && shading_language_version_minor >= 3) {
location = glGetAttribLocation(m_shaderProgram,name.c_str());
} else {
location = glGetAttribLocationARB(m_shaderProgram,name.c_str());
}
if (location != -1)
{
// Location found: add it to the cache
m_vertexAttribs.insert(std::make_pair(name, location));
}
else
{
// Error: location not found
err() << "Vertex attrib " << name << " not found in shader" << std::endl;
}
return location;
}
}
////////////////////////////////////////////////////////////
int Shader::getParamLocation(const std::string& name)
{
// Check the cache
ParamTable::const_iterator it = m_params.find(name);
if (it != m_params.end())
{
// Already in cache, return it
return it->second;
}
else
{
// Not in cache, request the location from OpenGL
int location;
if (shading_language_version_major >= 3 && shading_language_version_minor >= 3) {
location = glGetUniformLocation(m_shaderProgram, name.c_str());
} else {
location = glGetUniformLocationARB(m_shaderProgram, name.c_str());
}
if (location != -1)
{
// Location found: add it to the cache
m_params.insert(std::make_pair(name, location));
}
else
{
// Error: location not found
err() << "Parameter " << name << " not found in shader" << std::endl;
}
return location;
}
}
unsigned int Shader::getHandle() {
return m_shaderProgram;
}
unsigned int Shader::getVersionMajor() {
//ensureGlContext();
const GLubyte* glslversion = glGetString(GL_SHADING_LANGUAGE_VERSION);
if (glslversion)
return glslversion[0] - '0';
return 2;
}
unsigned int Shader::getVersionMinor() {
//ensureGlContext();
const GLubyte* glslversion = glGetString(GL_SHADING_LANGUAGE_VERSION);
if (glslversion)
return glslversion[1] - '0';
return 0;
}
}
} // namespace sf
How to link an external texture to an SFML shader ?