Hi I’ve written this OpenGL 3.2 / GLSL 1.50 core app to display a triangle with a texture on it but it only renders in one color. Probably because a problem with texture coords? No OpenGL error code is set! So it must be logic.
#define GL3_PROTOTYPES
#include <GL3/gl3.h>
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <glm/gtx.hpp>
#include <iostream>
#include <fstream>
#include <stack>
namespace glm {
using namespace gtx;
namespace gtx {
using namespace transform2;
}
}
void glError(const char *file, int line) {
GLenum err{glGetError()};
while(err!=GL_NO_ERROR) {
std::string error;
switch(err) {
case GL_INVALID_OPERATION: error="INVALID_OPERATION"; break;
case GL_INVALID_ENUM: error="INVALID_ENUM"; break;
case GL_INVALID_VALUE: error="INVALID_VALUE"; break;
case GL_OUT_OF_MEMORY: error="OUT_OF_MEMORY"; break;
}
std::cerr<<"GL_"<<error<<" - "<<file<<':'<<line<<std::endl;
err=glGetError();
}
}
int main() {
//Initialization
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION,3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION,2);
SDL_Init(SDL_INIT_VIDEO);
const int r_width{640},r_height{480};
SDL_WindowID window{SDL_CreateWindow("Foo",SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,r_width,r_height,SDL_WINDOW_OPENGL|SDL_WINDOW_SHOWN)};
SDL_GLContext glcontext{SDL_GL_CreateContext(window)};
std::cout<<"OpenGL "<<glGetString(GL_VERSION)<<" (GLSL "<<glGetString(GL_SHADING_LANGUAGE_VERSION)<<')'<<std::endl;
//Load texture
SDL_Surface *imagesurface{IMG_Load("Lenna.png")};
GLuint textureid;
glGenTextures(1,&textureid);
glBindTexture(GL_TEXTURE_2D,textureid);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,imagesurface->w,imagesurface->h,0,GL_RGB,GL_UNSIGNED_BYTE,imagesurface->pixels);
SDL_FreeSurface(imagesurface);
//Create shaders and shader program
GLuint vshader{glCreateShader(GL_VERTEX_SHADER)},fshader{glCreateShader(GL_FRAGMENT_SHADER)};
GLuint program{glCreateProgram()};
{
std::ifstream source_file{"image.vert"};
std::string data;
std::getline(source_file,data,'\0');
const GLchar *vshader_source{data.c_str()};
glShaderSource(vshader,1,&vshader_source,NULL);
}
{
std::ifstream source_file{"image.frag"};
std::string data;
std::getline(source_file,data,'\0');
const GLchar *fshader_source{data.c_str()};
glShaderSource(fshader,1,&fshader_source,NULL);
}
glCompileShader(vshader);
glCompileShader(fshader);
glAttachShader(program,vshader);
glAttachShader(program,fshader);
glLinkProgram(program);
GLint matrixloc{glGetUniformLocation(program,"projmat")};
GLint matrix2loc{glGetUniformLocation(program,"modelmat")};
//Create geometry
GLuint tris,coords,vao;
const GLfloat vertices[3*2]{0.0f,0.0f, 0.0f,1.0f, 1.0f,1.0f};
const GLfloat texcoords[3*2]{0.0f,0.0f, 0.0f,1.0f, 1.0f,1.0f};
glGenVertexArrays(1,&vao);
glBindVertexArray(vao);
glGenBuffers(1,&tris);
glBindBuffer(GL_ARRAY_BUFFER,tris);
glBufferData(GL_ARRAY_BUFFER,sizeof(vertices),&vertices[0],GL_STATIC_DRAW);
const GLint location{glGetAttribLocation(program,"vert")};
glVertexAttribPointer(location,2,GL_FLOAT,GL_FALSE,0,NULL);
glEnableVertexAttribArray(location);
glGenBuffers(1,&coords);
glBindBuffer(GL_ARRAY_BUFFER,coords);
glBufferData(GL_ARRAY_BUFFER,sizeof(texcoords),&texcoords[0],GL_STATIC_DRAW);
const GLint coordloc{glGetAttribLocation(program,"texcoord")};
glVertexAttribPointer(coordloc,2,GL_FLOAT,GL_FALSE,0,NULL);
glEnableVertexAttribArray(coordloc);
GLint texloc{glGetUniformLocation(program,"tex")};
//Render
glm::mat4 projmat;
glm::mat4 modelmat;
projmat*=glm::perspective(45.0f, float(r_width/r_height), 0.1f, 100.0f);
modelmat*=glm::translate(glm::vec3{0.0f,5.0f,0.0f});
glUseProgram(program);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,textureid);
glUniform1i(texloc,0);
glUniformMatrix4fv(matrixloc,1,GL_TRUE,&projmat[0][0]);
glUniformMatrix4fv(matrix2loc,1,GL_TRUE,&modelmat[0][0]);
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES,0,3);
glError(__FILE__,__LINE__);
SDL_GL_SwapWindow(window);
SDL_Delay(600);
//Quit
glDeleteShader(vshader);
glDeleteShader(fshader);
glDeleteProgram(program);
glDeleteTextures(1,&textureid);
SDL_GL_DeleteContext(glcontext);
SDL_DestroyWindow(window);
SDL_Quit();
}
#version 150
uniform mat4 projmat;
uniform mat4 modelmat;
in vec2 vert;
in vec2 texcoord;
out vec2 coord;
void main() {
coord=texcoord;
gl_Position=projmat*modelmat*vec4(vert,0,0);
}
#version 150
uniform sampler2D tex;
in vec2 coord;
out vec4 color;
void main() {
color=texture(tex,coord);
}