In this program the 3 triangles aren't drawn, even when I replace the texture by vec4(0.0f, 0.5f, 0.0f, 1.0f);
, trying to draw the third triangle in green:
#define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h>
#include <glad/gl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
#include <time.h>
#include <errno.h>
#define STB_IMAGE_IMPLEMENTATION
#include "./stb/stb_image.h"
void checkGLError(char * a) {
GLenum err;
while((err = glGetError()) != GL_NO_ERROR){
printf("GL_ERROR: %d (%s)\n",err,a);
}
}
const char * vsprog_core =
"#version 330 core\n"
"layout (location = 0) in vec3 vPos;\n"
"layout (location = 1) in vec2 vTexCoords;\n"
"\n"
"out vec2 TexCoords;\n"
"flat out int TexID;\n"
"\n"
"uniform int s;\n"
"\n"
"void main()\n"
"{\n"
" TexCoords = vTexCoords;\n"
" TexID = s;\n"
" gl_Position = vec4(vPos, 1.0f); \n"
"}\n";
const char * fsprog_core =
"#version 330 core\n"
"out vec4 FragColor;\n"
"\n"
"in vec2 TexCoords;\n"
"flat in int TexID;\n"
"\n"
"uniform sampler2DArray Textures;\n"
"\n"
"void main()\n"
"{\n"
" vec2 uv = TexCoords;\n"
" vec4 t = texture(Textures, vec3(uv, TexID));\n"
" if(TexID == 2) t = vec4(0.0f, 0.5f, 0.0f, 1.0f);\n"
" FragColor = t;\n"
"}\n";
void framebuffer_size_callback(GLFWwindow* window, int width, int height) {
glViewport(0, 0, width, height);
}
int main( int argc, char *argv[ ], char *envp[ ] ) {
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_SAMPLES, 4);
int width = 800;
int height = 600;
GLFWwindow* window = glfwCreateWindow(width, height, "DE", NULL, NULL);
if (window == NULL) {
printf("\nFailed to create GLFW window.\n");
glfwTerminate();
exit(EXIT_FAILURE);
}
glfwMakeContextCurrent(window);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
// glad: load all OpenGL function pointers
if (!gladLoadGL(glfwGetProcAddress)) {
printf("\nFailed to initialize GLAD.\n");
glfwTerminate();
exit(EXIT_FAILURE);
}
const GLubyte* renderer;
const GLubyte* version;
renderer = glGetString(GL_RENDERER);
version = glGetString(GL_VERSION);
printf("\nRenderer: %s", renderer);
printf("\nOpenGL version supported %s\n", version);
GLint value;
glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &value);
printf("\nGL_MAX_ARRAY_TEXTURE_LAYERS: %d\n", value);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glEnable(GL_MULTISAMPLE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
int texturecnt = 0;
GLuint texture_array;
glGenTextures(1,&texture_array);
glBindTexture(GL_TEXTURE_2D_ARRAY,texture_array);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 4096, 4096, 8,
0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
int iwidth, iheight, nrChannels;
//stbi_set_flip_vertically_on_load(1);
unsigned char *data = stbi_load("./rock.png", &iwidth, &iheight, &nrChannels, 0);
if(data) {
int mode = GL_RED;
if(nrChannels == 2) mode = GL_RG;
if(nrChannels == 3) mode = GL_RGB;
if(nrChannels == 4) mode = GL_RGBA;
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, texturecnt,
iwidth, iheight, 1, mode, GL_UNSIGNED_BYTE, data);
checkGLError("load texture");
} else {
printf("\nFailed to load texture: %d.\n",texturecnt);
}
stbi_image_free(data);
texturecnt++;
data = stbi_load("./ship.jpg", &iwidth, &iheight, &nrChannels, 0);
if(data) {
int mode = GL_RED;
if(nrChannels == 3) mode = GL_RGB;
if(nrChannels == 4) mode = GL_RGBA;
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, texturecnt,
iwidth, iheight, 1, mode, GL_UNSIGNED_BYTE, data);
checkGLError("load texture");
} else {
printf("\nFailed to load texture: %d.\n",texturecnt);
}
stbi_image_free(data);
texturecnt++;
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
GLfloat vertices[3][3*3] = {
{ -0.5f, -0.5f, 0.0f, // left
0.5f, -0.5f, 0.0f, // right
0.0f, 0.5f, 0.0f }, // top
{ -0.5f-1.0, -0.5f, 0.0f, // left
0.5f-1.0, -0.5f, 0.0f, // right
0.0f-1.0, 0.5f, 0.0f }, // top
{ -0.5f+1.0, -0.5f, 0.0f, // left
0.5f+1.0, -0.5f, 0.0f, // right
0.0f+1.0, 0.5f, 0.0f } // top
};
GLfloat texcoords[3*2] = {
0.0, 1.0,
1.0, 1.0,
0.5, 0.0
};
GLuint vao[3];
GLuint vbo[3];
GLuint vbotex[3];
for(int i=0; i<3; i++) {
// VAO:
glGenVertexArrays(1, &(vao[i]));
glBindVertexArray(vao[i]);
// VBO:
glGenBuffers(1,&(vbo[i]));
glBindBuffer(GL_ARRAY_BUFFER,vbo[i]);
glBufferData(GL_ARRAY_BUFFER, 3 * 3 * sizeof(GLfloat), &(vertices[i][0]), GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER,0);
// VBO:
glGenBuffers(1,&(vbotex[i]));
glBindBuffer(GL_ARRAY_BUFFER,vbotex[i]);
glBufferData(GL_ARRAY_BUFFER, 2 * 3 * sizeof(GLfloat), &texcoords[0], GL_STATIC_DRAW);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER,0);
}
// End VAO:
glBindVertexArray(0);
//////////////////////////////////////////////////////////
//
// Shaders:
//
GLint params;
GLint len;
GLuint vscore = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vscore, 1, &vsprog_core, NULL);
glCompileShader(vscore);
glGetShaderiv(vscore,GL_COMPILE_STATUS,¶ms);
if(params == GL_FALSE) {
GLchar log[100000];
glGetShaderInfoLog(vscore,100000,&len,log);
printf("\n\n%s\n\n",log);
exit(EXIT_FAILURE);
}
GLuint fscore = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fscore, 1, &fsprog_core, NULL);
glCompileShader(fscore);
glGetShaderiv(fscore,GL_COMPILE_STATUS,¶ms);
if(params == GL_FALSE) {
GLchar log[100000];
glGetShaderInfoLog(fscore,100000,&len,log);
printf("\n\n%s\n\n",log);
exit(EXIT_FAILURE);
}
GLuint shader_program_core = glCreateProgram();
glAttachShader(shader_program_core, fscore);
glAttachShader(shader_program_core, vscore);
glLinkProgram(shader_program_core);
glGetProgramiv(shader_program_core,GL_LINK_STATUS,¶ms);
if(params == GL_FALSE) {
GLchar log[100000];
glGetProgramInfoLog(shader_program_core,100000,&len,log);
printf("\n\n%s\n\n",log);
fflush(stdout);
exit(EXIT_FAILURE);
}
glDeleteShader(vscore);
glDeleteShader(fscore);
GLuint sloc = glGetUniformLocation(shader_program_core,"s");
while(!glfwWindowShouldClose(window)) {
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shader_program_core);
glBindTexture(GL_TEXTURE_2D_ARRAY, texture_array);
glBindVertexArray(vao[0]);
glUniform1i(sloc,0);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(vao[1]);
glUniform1i(sloc,1);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(vao[2]);
glUniform1i(sloc,2);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
checkGLError("draw");
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwDestroyWindow(window);
glfwTerminate();
exit(EXIT_SUCCESS);
}
What am I doing wrong?
The issue in your code, is that you are not clearing the depth buffer, along with the color buffer in your render loop. Since you have depth testing enabled (glEnable(GL_DEPTH_TEST)), the first triangle you draw (at z = 0.0) will write to the depth buffer, causing subsequent triangles to fail the depth test and not be rendered.
How fix:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
Why this happens:
Also, i added line in while loop to clear depth too:
while(!glfwWindowShouldClose(window)) {
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Fixed: Clear depth