Reputation: 88
I have tried to put a texture on a square, made out of two triangles, but it isn't displaying on the square and it is on both triangles seperately. I followed many tutorials, but they don't go into much details on how to fix this. It seems, that I need to change my shader, but I don't know how to go about this. Please tell me what to change!
This is a picture of the window:
This is my code:
#define GLEW_STATIC
#define STB_IMAGE_IMPLEMENTATION
#include<stdio.h>
#include<GL/glew.h>
#include<GLFW/glfw3.h>
#include<stdbool.h>
#include<string.h>
#include<stb/stb_image.h>
GLint uniColor;
void key_callback();
int main(){
if(!glfwInit()){
printf("Failed to initialize glfw!\n");
return 1;
}else{
printf("Successfully initialized glfw!\n");
}
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window = glfwCreateWindow(1054, 1057, "Title", NULL, NULL);
glfwSetKeyCallback(window, key_callback);
if(!window){
printf("Window creation failed!\n");
return 1;
}else{
printf("Window created successfully!\n");
}
glfwMakeContextCurrent(window);
glewExperimental = GL_TRUE;
if(glewInit() != GLEW_OK){
printf("Failed to initialize glew!\n");
return 1;
}else{
printf("Successfully initialized glew!\n");
}
glfwSwapInterval(1);
float Vertices[] = {
-0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
0.5f, -0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f
};
GLuint indices[] = {
0, 2, 1,
0, 3, 2
};
float VerticesSquare[] = {
-0.5f, 0.5f, 0.0f,
0.5f, 0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
-0.5f, -0.5f, 0.0f
};
printf("GLfloat variable called successfully\n");
GLuint ShaderProgram = glCreateProgram();
GLuint ShaderObjv = glCreateShader(GL_VERTEX_SHADER);
GLuint ShaderObjf = glCreateShader(GL_FRAGMENT_SHADER);
const GLchar* pvs[1];
const GLchar* pfs[1];
const char* pVertexShaderText = "#version 330\nlayout(location = 0) in vec3 Position;\nlayout(location = 1) in vec3 incolor;\nlayout(location = 2) in vec2 Tex;\nout vec3 outcolor;\nout vec2 texcoords;\nvoid main(){gl_Position = vec4(Position.x, Position.y, Position.z, 1.0);\noutcolor = incolor;\ntexcoords = Tex;}";
const char* pFragmentShaderText = "#version 330\nuniform vec3 color;\nuniform sampler2D tex0;\nin vec3 outcolor;\nin vec2 texcoords;\nout vec4 FragColor;\nvoid main(){FragColor = texture(tex0, texcoords);}";
pvs[0] = pVertexShaderText;
pfs[0] = pFragmentShaderText;
GLint LenghtsVertex[1];
GLint LenghtsFragment[1];
LenghtsVertex[0] = strlen(pVertexShaderText);
LenghtsFragment[0] = strlen(pFragmentShaderText);
glShaderSource(ShaderObjv, 1, pvs, LenghtsVertex);
glShaderSource(ShaderObjf, 1, pfs, LenghtsFragment);
glCompileShader(ShaderObjv);
glCompileShader(ShaderObjf);
GLint successvs;
glGetShaderiv(ShaderObjv, GL_COMPILE_STATUS, &successvs);
if (!successvs) {
GLchar InfoLog1[1024];
glGetShaderInfoLog(ShaderObjv, sizeof(InfoLog1), NULL, InfoLog1);
fprintf(stderr, "Error compiling shader type %d: '%s'\n", GL_VERTEX_SHADER, InfoLog1);
}
GLint successfs;
glGetShaderiv(ShaderObjf, GL_COMPILE_STATUS, &successfs);
if (!successfs) {
GLchar InfoLog2[1024];
glGetShaderInfoLog(ShaderObjf, sizeof(InfoLog2), NULL, InfoLog2);
fprintf(stderr, "Error compiling shader type %d: '%s'\n", GL_FRAGMENT_SHADER, InfoLog2);
}
glAttachShader(ShaderProgram, ShaderObjv);
glAttachShader(ShaderProgram, ShaderObjf);
glLinkProgram(ShaderProgram);
glValidateProgram(ShaderProgram);
glUseProgram(ShaderProgram);
GLint uniColor = glGetUniformLocation(ShaderProgram, "color");
GLint tex0uni = glGetUniformLocation(ShaderProgram, "tex0");
glUniform3f(uniColor, 1.0f, 0.0f, 0.0f);
glUniform1i(tex0uni, 0);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
GLuint VBO;
GLuint VAO = 0;
GLuint EBO;
glGenBuffers(1, &VBO);
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &EBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
printf("Buffer created successfully\n");
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
printf("Buffer data set up successfully\n");
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
printf("Enabling buffer successfull\n");
glBindBuffer(GL_ARRAY_BUFFER, VBO);
printf("Binding buffer successfull\n");
int width, height, num;
unsigned char* bytes = stbi_load("image.png", &width, &height, &num, 0);
GLuint texture;
glGenTextures(1, &texture);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
float flatcolor[] = {1.0f, 1.0f, 1.0f, 1.0f};
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, flatcolor);
printf("Set parameters successfully\n");
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, bytes);
glGenerateMipmap(GL_TEXTURE_2D);
printf("Texture set successfully\n");
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
printf("First pointer succeeded\n");
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
printf("Second pointer succeeded\n");
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
printf("Third pointer succeeded\n");
printf("Setting up VectexAttribPointer successfull\n");
while(!glfwWindowShouldClose(window)){
glfwPollEvents();
glClear(GL_COLOR_BUFFER_BIT);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
//glDrawArrays(GL_TRIANGLES, 0, 3);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
GLenum err;
if((err = glGetError()) != GL_NO_ERROR){
printf("OpenGL error: %d\n", err);
}
glfwSwapBuffers(window);
}
return 0;
}
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
if(key == GLFW_KEY_R && action == GLFW_PRESS){
glUniform3f(uniColor, 1.0f, 0.0f, 0.0f);
}else if(key == GLFW_KEY_G && action == GLFW_PRESS){
glUniform3f(uniColor, 0.0f, 1.0f, 0.0f);
}else if(key == GLFW_KEY_B && action == GLFW_PRESS){
glUniform3f(uniColor, 0.0f, 0.0f, 1.0f);
}
}
Upvotes: 1
Views: 184
Reputation: 88
Solved! I had to add glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
, because of the odd resolution of the image. As far as I know it limits the bytes sent at the same time to only 1.
Upvotes: 1
Reputation: 1098
Your problem has nothing to do with the shader. The cause are wrong texture coordinates here:
float Vertices[] = {
-0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
-0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f
};
The x and y coordinates and the texture coordinates only match up in the first line.
This is the corrected version:
float Vertices[] = {
-0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,
0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f
};
Upvotes: 0