I just don't understand why it does not work - it just shows a white screen... (or a black one, because glClearColor
)
PS. > the texture also broke everything else...
I checked the shaders and the code: no errors, no responses, nothing. Including the texture.
I think the shaders are right, but i don't know about anything else. I also have all the libraries: GLEW, GLFW, OPENGL, a single header file copied from stb_image...
Here is the code:
#include <iostream>
#include <fstream>
#include <string>
#include "GL/glew.h"
#include "GLFW/glfw3.h"
#define ASSERT(x) if(!(x)) __debugbreak();
#define CALL(x) OpenGlClError(); x; ASSERT(OpenGlError(#x, __LINE__, __FILE__));
#define STB_IMAGE_IMPLEMENTATION
#include "extern/stb_image/stb_image_vendor/stb_image.h"
void OpenGlClError() {
while (glGetError());
}
bool OpenGlError(const char* func, int line, const char* file) {
while (GLenum error = glGetError()) {
std::cout << "GLTest: OPENGL ERROR: " << error << " in function " << func << " at line " << line << ", FILE: " << file << "\n";
return false;
}
return true;
}
#define ASSERT(x) if(!(x)) __debugbreak();
#define CALL(x) OpenGlClError(); x; ASSERT(OpenGlError(#x, __LINE__, __FILE__));
class Texture {
private:
unsigned int TextID;
std::string FilePath;
unsigned char* LocalBuffer;
int Width, Height, BytesPixel;
public:
Texture(const std::string path)
: TextID(0), FilePath(path), LocalBuffer(nullptr), Width(0), Height(0), BytesPixel(0) {
CALL(glGenTextures(1, &TextID));
CALL(glBindTexture(GL_TEXTURE_2D, TextID));
stbi_set_flip_vertically_on_load(1);
LocalBuffer = stbi_load(path.c_str(), &Width, &Height, &BytesPixel, 4);
CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, Width, Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, LocalBuffer));
CALL(glBindTexture(GL_TEXTURE_2D, 0));
if (LocalBuffer) { //if localbuffer exists
stbi_image_free(LocalBuffer);
}
}
~Texture() {
glDeleteTextures(1, &TextID);
}
void Bind(unsigned int slot = 0){
CALL(glActiveTexture(GL_TEXTURE0 + slot));
CALL(glBindTexture(GL_TEXTURE_2D, TextID));
}
void Unbind() {
glBindTexture(GL_TEXTURE_2D, 0);
}
};
static std::string ReadShader(const std::string& filename) {
std::ifstream stream;
std::string line;
std::string str;
stream.open(filename);
while (getline(stream, line)) {
str.append(line).append("\n");
}
std::cout << str;
stream.close();
return str;
}
static unsigned int CompileShader(const std::string& source, unsigned int type) {
unsigned int shader = glCreateShader(type);
const char* src = source.c_str();
glShaderSource(shader, 1, &src, nullptr);
glCompileShader(shader);
int result;
glGetShaderiv(shader, GL_COMPILE_STATUS, &result);
// i - int
// v - vector
if (result == GL_FALSE) {
std::cout << "Shader cannot be compiled.\n" << (type == GL_VERTEX_SHADER ? "vertex s." : "fragments.") << "\n";
int length;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
char* message = (char*)_malloca(length * sizeof(char));
glGetShaderInfoLog(shader, length, &length, message);
std::cout << message << "\n";
glDeleteShader(shader);
}
return shader;
}
static int CreateShader(const std::string& vShader, const std::string& fShader) {
unsigned int program = glCreateProgram();
unsigned int vs = CompileShader(vShader, GL_VERTEX_SHADER);
unsigned int fs = CompileShader(fShader, GL_FRAGMENT_SHADER);
glAttachShader(program, vs);
glAttachShader(program, fs);
glLinkProgram(program);
glValidateProgram(program);
glDeleteShader(vs);
glDeleteShader(fs);
return program;
}
int main() {
glfwInit();
//make window
GLFWwindow* window;
//std::cout << "GLTest:" << glGetString(GL_VERSION) << "\n";
window = glfwCreateWindow(800, 500, "Modern OpenGL Test", NULL, NULL);
glfwMakeContextCurrent(window);
glewInit();
float texver[16] = {
-1.0f, -1.0f , 0.0f, 0.0f,
1.0f, -1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 1.0f, 1.0f,
-1.0f, -1.0f, 0.0f, 1.0f
};
float texindex[6] = {
0, 1, 2,
2, 3, 0
};
float vertices[12] = {
1.0f, 1.0f,
0.0f, -1.0f,
1.0f, -1.0f,
-1.0f, 1.0f,
0.0f, 1.0f,
-1.0f, -1.0f
};
//unsigned int varray; //< dont actually need it...
//glGenVertexArrays(1, &varray);
//glBindVertexArray(varray);
//unsigned int vb;
//glGenBuffers(1, &vb);
//glBindBuffer(GL_ARRAY_BUFFER, vb);
//glBufferData(GL_ARRAY_BUFFER, 6 * 2 * sizeof(float), vertices, GL_STATIC_DRAW);
//
//glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0); //said hey we have this set up like that, links in vertex array
//glEnableVertexAttribArray(0); //yea remember it
unsigned int tb;
glGenBuffers(1, &tb);
glBindBuffer(GL_ARRAY_BUFFER, tb);
glBufferData(GL_ARRAY_BUFFER, 4 * 4 * sizeof(float), texver, GL_STATIC_DRAW);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, 0); //said hey we have this set up like that, links in vertex array
glEnableVertexAttribArray(0); //yea remember it
unsigned int shaders = CreateShader(ReadShader("shaders/basic_texture_vertex.shader"), ReadShader("shaders/basic_texture_fragment.shader"));
glUseProgram(shaders);
Texture tt("../!Assets/editor/img/intro_logo.png");
tt.Bind();
CALL(int location = glGetUniformLocation(shaders, "u_Texture"));
CALL(glUniform1i(location, 0));
CALL(glBindBuffer(GL_ARRAY_BUFFER, 0));
while (!glfwWindowShouldClose(window)) {
glClear(GL_COLOR_BUFFER_BIT);
glClearColor(1, 1, 1, 1);
//Drawing
glDrawArrays(GL_TRIANGLES, 0, 6 * 2);
glfwSwapBuffers(window);
glfwPollEvents();
}
glDeleteProgram(shaders);
glfwTerminate();
}
You missed to specify the vertex attribute for the texture coordinates. For instance
unsigned int tb;
glGenBuffers(1, &tb);
glBindBuffer(GL_ARRAY_BUFFER, tb);
glBufferData(GL_ARRAY_BUFFER, 4 * 4 * sizeof(float), texver, GL_STATIC_DRAW);
// vertex cooridnates
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, 0);
glEnableVertexAttribArray(0);
// texture coordinates
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(float)*4, (void*)(sizeof(float)*2));
glEnableVertexAttribArray(1);
The last argument of glDrawArrays
is the number of vertices. Since you just have 4 vertices, the argument cannot be 6*2
.
Anyway, since you have specified an array indices it seems that you want to specify an Index buffer. You have to use glDrawElements
for indexed rendering.
The indices have to be an integral data type:
int texindex[6] = {
0, 1, 2,
0, 2, 3
};
Generate the index (GL_ELEMENT_ARRAY_BUFFER
) buffer:
unsigned int ibo;
glGenBuffers(1, &ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(int), texindex, GL_STATIC_DRAW);
Draw the tringles:
glDrawArrays(GL_TRIANGLES, 0, 6 * 2);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);