Update 2 works, it was a wrong allert
Update 2 (using vbo vertex- and fragment-shaders) but it still don't works
#include "GL/glxew.h"
#include "GL/glext.h"
#include "GL/glu.h"
#include "GL/freeglut.h"
#include <iostream>
GLint attribute;
GLuint program;
void gen_texture(GLuint &texture, int width, int height)
{
GLuint fb;
glGenFramebuffers(1, &fb);
glGenTextures(1, &texture);
glBindFramebuffer(GL_FRAMEBUFFER, fb);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGBA,
width, height,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glEnable(GL_TEXTURE_2D);
glBindFramebuffer(GL_FRAMEBUFFER, fb);
glClearColor(1,1,1,0);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(program);
glEnableVertexAttribArray(attribute);
GLfloat vertex_data[]
{
1.0f, 0.0f,
0.0f, 0.0f,
0.0f, 1.0f,
1.0f, 0.0f,
0.0f, 1.0f,
1.0f, 1.0f
};
glVertexAttribPointer(
attribute,
2,
GL_FLOAT,
GL_FALSE,
0,
vertex_data
);
glDrawArrays(GL_TRIANGLES, 0, 6);
glDisableVertexAttribArray(attribute);
}
void init_layout()
{
GLint compile_ok = GL_FALSE, link_ok = GL_FALSE;
GLuint vs, fs;
vs = glCreateShader(GL_VERTEX_SHADER);
const char *vs_source =
"#version 120\n" // OpenGL 2.1
"attribute vec2 coord2d; "
"void main(void) { "
" gl_Position = vec4(coord2d, 0.0, 1.0); "
"}";
glShaderSource(vs, 1, &vs_source, 0);
glCompileShader(vs);
glGetShaderiv(vs, GL_COMPILE_STATUS, &compile_ok);
if (0 == compile_ok)
{
std::cerr << "[texture_layout/init_layout] fehler im vertex shader\n";
exit(1);
}
fs = glCreateShader(GL_FRAGMENT_SHADER);
const char *fs_source =
"#version 120\n" // OpenGL 2.1
"void main(void) { "
" gl_FragColor[0] = 0.8f; "
" gl_FragColor[1] = 0.5f;"
" gl_FragColor[2] = 0.0f; "
"}";
glShaderSource(fs, 1, &fs_source, 0);
glCompileShader(fs);
glGetShaderiv(fs, GL_COMPILE_STATUS, &compile_ok);
if (0 == compile_ok)
{
std::cerr << "[texture_layout/init_layout] fehler im fragment shader\n";
exit(1);
}
program = glCreateProgram();
glAttachShader(program, vs);
glAttachShader(program, fs);
glLinkProgram(program);
glGetProgramiv(program, GL_LINK_STATUS, &link_ok);
if (!link_ok)
{
std::cerr << "[texture_layout/init_layout] fehler in glLinkProgram\n";
exit(1);
}
const char* attribute_name = "coord2d";
attribute = glGetAttribLocation(program, attribute_name);
if (attribute == -1) {
std::cerr << "Could not bind attribute " << attribute_name << "\n";
exit(1);
}
}
int main(int argc, char **argv)
{
glutInit (&argc, argv);
glutInitContextProfile(GLUT_CORE_PROFILE);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowSize (500, 500);
glutCreateWindow ("");
glewExperimental=GL_TRUE;
GLenum err=glewInit();
if(err!=0)
{
std::cerr << glewGetErrorString(err) << std::endl;
exit(1);
}
GLenum error;
GLuint texture;
while ( ( error = glGetError() ) != GL_NO_ERROR)
{
std::cerr << std::hex << error << "\n";
}
init_layout();
gen_texture(texture, 200, 200);
GLvoid *tex_data = new GLubyte[4*200*200];
glBindTexture(GL_TEXTURE_2D, texture);
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex_data);
return 0;
}
Update 1 (using vbo instead of glBegin)
now my code should draw a red triangle using vbo, but it doesn't
void gen_texture(GLuint &color, int width, int height)
{
GLuint fb;
glGenFramebuffers(1, &fb);
glGenTextures(1, &color);
glBindFramebuffer(GL_FRAMEBUFFER, fb);
glBindTexture(GL_TEXTURE_2D, color);
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGBA,
width, height,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glEnable(GL_TEXTURE_2D);
glBindFramebuffer(GL_FRAMEBUFFER, fb);
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
glViewport(0,0,width,height);
glOrtho(0,width,0,height,0,128);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
//glDisable(GL_CULL_FACE);
glColor3f(1.f, .0f, .0f);
GLfloat vertices[6] =
{
0, 0,
0, (GLfloat)height,
(GLfloat)width, (GLfloat)height,
};
unsigned short indices[] = {0, 1, 2};
GLuint vbo;
glGenBuffersARB(1, &vbo);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, 6*sizeof(GLfloat), vertices, GL_STATIC_DRAW_ARB);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, 0);
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, vertices);
}
Original 2:
I have a function that should draw a red square into a texture with the glBegin directive. But the only thing I got to work is
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
I've tested it with multiple colors. But that part do not work:
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
glViewport(0,0,width,height);
glOrtho(0,width,0,height,0,128);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glDisable(GL_DEPTH_TEST);
glColor3f(1.f, .0f, .0f);
glBegin(GL_QUADS);
glVertex2f(0, 0);
glVertex2f(0, height);
glVertex2f(width, height);
glVertex2f(width, 0);
glEnd();
Here is the full function:
void gen_texture(GLuint &color, int width, int height)
{
GLuint fb;
glGenFramebuffers(1, &fb);
glGenTextures(1, &color);
glBindFramebuffer(GL_FRAMEBUFFER, fb);
glBindTexture(GL_TEXTURE_2D, color);
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGBA,
width, height,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glEnable(GL_TEXTURE_2D);
glBindFramebuffer(GL_FRAMEBUFFER, fb);
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
glViewport(0,0,width,height);
glOrtho(0,width,0,height,0,128);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
//glDisable(GL_CULL_FACE);
glColor3f(1.f, .0f, .0f);
glBegin(GL_QUADS);
glVertex2f(0, 0);
glVertex2f(0, height);
glVertex2f(width, height);
glVertex2f(width, 0);
glEnd();
}
Original Post:
I have a function that should draw a red square into a texture, but when I call the function for generating the texture and then I want to check the generated texture data, with the glGetTexImage function, I get a null-pointer.
#include "GL/glxew.h"
#include "GL/glext.h"
#include "GL/glu.h"
#include "GL/freeglut.h"
#include <iostream>
GLuint texture;
GLvoid *tex_data;
void gen_texture(GLuint &color, int width, int height)
{
GLuint fb;
glGenFramebuffers(1, &fb);
glGenTextures(1, &color);
glBindFramebuffer(GL_FRAMEBUFFER, fb);
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGBA,
width, height,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glEnable(GL_TEXTURE_2D);
glBindFramebuffer(GL_FRAMEBUFFER, fb);
glViewport(0, 0, width, height);
glClearColor(1,1,1,0);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
glOrtho (0, width, height, 0, 0, 1);
glMatrixMode (GL_MODELVIEW);
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
glColor4f(1.f, .0f, .0f, .5f);
glBegin(GL_QUADS);
glVertex2f(0, 0);
glVertex2f(0, height);
glVertex2f(width, height);
glVertex2f(width, 0);
glEnd();
}
int main(int argc, char **argv)
{
glutInit (&argc, argv);
glutInitContextVersion(3, 2);
glutInitContextProfile(GLUT_CORE_PROFILE);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowSize (500, 500);
glutCreateWindow ("");
glewExperimental=GL_TRUE;
GLenum err=glewInit();
if(err!=0)
{
std::cerr << glewGetErrorString(err) << std::endl;
exit(1);
}
GLenum error;
while ( ( error = glGetError() ) != GL_NO_ERROR)
{
std::cerr << std::hex << error << "\n";
}
gen_texture(texture, 200, 200);
glBindTexture(GL_TEXTURE_2D, texture);
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex_data);
if (tex_data == 0)
std::cerr << "Captain, eine Null an Board!\n";
return 0;
}
the tex_data is now a null-pointer
what am I doing wrong???
glutInitContextVersion(3, 2);
glutInitContextProfile(GLUT_CORE_PROFILE);
^^^^^^^^^^^^^^^^^ ok...
....
glBegin(GL_QUADS);
^^^^^^^^ wat
glBegin() and friends aren't valid calls in a Core context.
You'll have to get spun up on shaders and VBOs if you insist on Core.
Related
My code is giving me this error:
Exception thrown at 0x00007FFCF428A6CF (nvoglv64.dll) in program.exe:
0xC0000005: Access violation reading location 0x000001D6B603F000.
In the debug output window of Visual Studio I also see pdb not loaded for the nvoglv64.dll file.
since i've added this code to my openGL app:
data = stbi_load("src/pickaxe.png", &width, &height, &nrChannels, 0);
if (!data) {
std::cout << "swords image loaded incorrectly " << std::endl;
}
else {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
}
Is it caused because of loading the image or by function GLTEXIMAGE_2D ?
Here is my full code:
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
// global variables
int p_WIDTH = 1280;
int p_HEIGHT = 960;
int succes;
char info[512];
// buffers
// shader sources
const char* vertexShaderSource =
"#version 330 core\n"
"layout(location = 0)in vec3 _verts;\n"
"layout(location = 1)in vec2 _texCoords;\n"
"out vec2 texCoords;\n"
"void main(){\n"
"gl_Position = vec4(_verts, 1.0f);\n"
"texCoords = _texCoords;\n"
"};\0"
;
const char* fragmentShaderSource =
"#version 330 core\n"
"in vec2 texCoords;\n"
"out vec4 fragColor;\n"
"uniform sampler2D _texture1;\n"
"uniform sampler2D _texture2;\n"
"void main(){\n"
"fragColor = mix(texture(_texture1, texCoords), texture(_texture2, texCoords), 0.5f);\n"
"};\0"
;
// functions
void window_resize_callback(GLFWwindow* window, int width, int height) {
glViewport(0, 0, width, height);
}
int main() {
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_ANY_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window = glfwCreateWindow(p_WIDTH, p_HEIGHT, "getting_started_completed", NULL, NULL);
glfwMakeContextCurrent(window);
glfwSetFramebufferSizeCallback(window, window_resize_callback);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
// shaders
GLuint vertexShader, fragmentShader;
vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &succes);
if (!succes) {
glGetShaderInfoLog(vertexShader, 512, NULL, info);
std::cout << "VERTEX_SHADER_COMP_ERROR: " << info << std::endl;
}
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &succes);
if (!succes) {
glGetShaderInfoLog(fragmentShader, 512, NULL, info);
std::cout << "FRAGMENT_SHADER_COMP_ERROR: " << info << std::endl;
}
GLuint program = glCreateProgram();
glAttachShader(program, vertexShader);
glAttachShader(program, fragmentShader);
glLinkProgram(program);
glGetProgramiv(program, GL_COMPILE_STATUS, &succes);
if (!succes) {
glGetProgramInfoLog(program, 512, NULL, info);
std::cout << "PROGRAM_LINK_ERROR: " << info << std::endl;
}
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
// vertices
float vertices[] = {
-0.5f, -0.5f, 0.f, 0,0, // 0
0.5f, -0.5f, 0.f, 1,0, // 1
0.5f, 0.5f, 0.f, 1,1, // 2
-0.5f, 0.5f, 0.f, 0,1 // 3
};
unsigned int indices[] = {
0,1,2,
0,2,3
};
// buffers etc.
GLuint vbo, vao, ebo;
glGenVertexArrays(1, &vao);
glGenBuffers(1, &vbo);
glGenBuffers(1, &ebo);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5*sizeof(float), (void*)0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
// textures
unsigned int texture1, texture2;
glGenTextures(1, &texture1);
glBindTexture(GL_TEXTURE_2D, texture1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
int width, height, nrChannels;
stbi_set_flip_vertically_on_load(true);
unsigned char* data = stbi_load("src/dirt.jpg", &width, &height, &nrChannels, 0);
if (!data) {
std::cout << "dirt image loaded incorectly " << std::endl;
}
else {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
}
stbi_image_free(data);
glGenTextures(1, &texture2);
glBindTexture(GL_TEXTURE_2D, texture2);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
data = stbi_load("src/pickaxe.png", &width, &height, &nrChannels, 0);
if (!data) {
std::cout << "swords image loaded incorrectly " << std::endl;
}
else {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
}
glUseProgram(program);
glUniform1i(glGetUniformLocation(program, "_texture1"), 0);
glUniform1i(glGetUniformLocation(program, "_texture2"), 1);
while (!glfwWindowShouldClose(window)) {
glClearColor(0.f, 0.1f, 0.1f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture1);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture2);
glUseProgram(program);
glBindVertexArray(vao);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glfwPollEvents();
glfwSwapBuffers(window);
}
glDeleteVertexArrays(1, &vao);
glDeleteBuffers(1, &vbo);
glDeleteBuffers(1, &ebo);
glfwTerminate();
//std::cin.get();
return 0;
}
You want to load and image with 4 channels (GL_RGBA). There is no guarantee that the STB library generates an image with 4 channels. The actual number of channels is returned by the 4th argument of stbi_load. If the image doesn't have 4 channels, the subsequent call of glTexImage2D expects a larger buffer than you actually provide. That causes the access violation.
To solve the problem, you can force stbi_load to generate an image with 4 color channels by explicitly passing 4 as the last parameter:
data = stbi_load("src/pickaxe.png", &width, &height, &nrChannels, 4);
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I am learning OpenGL following https://learnopengl.com/ I wanted to take the 2D Texture code and put it into a class. The code works fine in the main file, but that same code, copy and pasted into the texture class, doesn't work at all. Leads to a black color. I've tried using error checking, but nothing comes up. I want to know why it isn't working.
Main.cpp File:
#include <iostream>
#include <chrono>
#include <thread>
#include "GL/glew.h"
#include "GLFW/glfw3.h"
#define STB_IMAGE_IMPLEMENTATION
#include "STB/stb_image.h"
#include "Shader.h"
#include "Texture2D.h"
using namespace std::chrono_literals;
//Keeps viewport same size of window when the window is resized
void framebuffer_size_callback(GLFWwindow* window, int width, int height) {
glViewport(0, 0, width, height);
}
void processInput(GLFWwindow* window) {
if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
if (glfwGetKey(window, GLFW_KEY_F) == GLFW_PRESS)
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
else
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
int main() {
stbi_set_flip_vertically_on_load(true);
//Vertices and Indices
float vertices[] = {
// positions // colors // texture coords
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // top right
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // bottom right
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // bottom left
-0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f // top left
};
unsigned int indices[] = { // note that we start from 0!
0, 2, 3, // first triangle
0, 1, 2 // second triangle
};
//GLFW Initialization
if (!glfwInit()) { std::cerr << "Shit, GLFW Didn't INIT Properly" << std::endl; std::this_thread::sleep_for(3s); return -1; }
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
//GLFW Window Creation
GLFWwindow* w = glfwCreateWindow(800,600,"WET ASS PUSSY",NULL,NULL);
if (!w) { glfwTerminate(); std::cerr << "Failed to Make Window" << std::endl; std::this_thread::sleep_for(3s); return -1; }
glfwMakeContextCurrent(w);
//GLEW Initialization
if (glewInit() != GLEW_OK) { glfwTerminate(); std::cerr << "Shit, GLEW Didn't Init Properly" << std::endl; std::this_thread::sleep_for(3s); return -1; }
std::cout << glGetString(GL_VERSION) << std::endl;
//Viewport and Window Resizing Callback Setup
glViewport(0, 0, 800, 600);
glfwSetFramebufferSizeCallback(w, framebuffer_size_callback); //Fn set as callback when resizing window
/*
//Create Texture
unsigned int texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
// set the texture wrapping/filtering options (on the currently bound texture object)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//Load Texture Data
int width, height, nrChannels;
unsigned char* data = stbi_load("Textures/stoneBrickWall.jpg", &width, &height, &nrChannels, 0);
if (data)
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
}
else
{
std::cout << "Failed to load texture" << std::endl;
}
stbi_image_free(data);
*/
Texture2D tex("Textures/stoneBrickWall.jpg", GL_RGB, GL_RGB, GL_REPEAT, GL_LINEAR);
//Vector Buffer/Element Buffer/Vector Array Handling
unsigned int vBuff;
glGenBuffers(1, &vBuff);
unsigned int EBO;
glGenBuffers(1, &EBO);
unsigned int VAO;
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, vBuff);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
//glBindTexture(GL_TEXTURE_2D, texture);
tex.use();
//Vertex Handling Instructions
//Position
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
//Color
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3*sizeof(float)));
glEnableVertexAttribArray(1);
//Texture
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
glEnableVertexAttribArray(2);
glBindVertexArray(0);
//Make Shader
Shader shader("Shader.vs", "Shader.fs");
shader.use();
//Render Loop
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
while (!glfwWindowShouldClose(w)) {
processInput(w);
glClear(GL_COLOR_BUFFER_BIT);
//render here--
shader.use();
glBindVertexArray(VAO);
tex.use();
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glUseProgram(0);
glBindVertexArray(0);
//--
glfwSwapBuffers(w);
glfwPollEvents();
}
//Cleanup
glfwDestroyWindow(w);
glfwTerminate();
return 0;
}
Texture2D.h:
#pragma once
#include "GL/glew.h"
#include <iostream>
class Texture2D {
public:
unsigned int ID = 0;
int width = 0, height = 0, nrChannels = 0;
Texture2D(const char* imgPath, GLint internalFormat, GLenum format, GLint sWrapMode, GLint tWrapMode, GLint minFilterMode, GLint magFilterMode);
Texture2D(const char* imgPath, GLint internalFormat, GLenum format, GLint wrapMode, GLint filterMode) { Texture2D(imgPath, internalFormat, format, wrapMode, wrapMode, filterMode, filterMode); }
void use();
void use(unsigned int textureUnitNum);
GLuint checkError(const char* context);
};
Texture2D.cpp:
#include "Texture2D.h"
#include "STB/stb_image.h"
Texture2D::Texture2D(const char* imgPath, GLint internalFormat, GLenum format, GLint sWrapMode, GLint tWrapMode, GLint minFilterMode, GLint magFilterMode) {
//Create Texture
glGenTextures(1, &ID);
glBindTexture(GL_TEXTURE_2D, ID);
// set the texture wrapping/filtering options (on the currently bound texture object)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//Load Texture Data
unsigned char* data = stbi_load("Textures/stoneBrickWall.jpg", &width, &height, &nrChannels, 0);
if (data)
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
}
else
{
std::cout << "Failed to load texture" << std::endl;
}
stbi_image_free(data);
checkError("Texture Creation");
}
void Texture2D::use() {
glBindTexture(GL_TEXTURE_2D, ID);
checkError("Binding Texture");
}
void Texture2D::use(unsigned int textureUnitNum) {
glActiveTexture(GL_TEXTURE0 + textureUnitNum);
use();
}
GLuint Texture2D::checkError(const char* context)
{
GLuint err = glGetError();
if (err > 0) {
std::cout << "0x" << std::hex << err << " glGetError() in " << context
<< std::endl;
}
return err;
}
This constructor is the problem:
Texture2D(const char* imgPath, GLint internalFormat, GLenum format, GLint wrapMode, GLint filterMode) {
Texture2D(imgPath, internalFormat, format, wrapMode, wrapMode, filterMode, filterMode);
}
This creates an anonymous local variable of type Texture2D and then throws it away, leaving the Texture2D object itself (whose constructor is now running) completely uninitialized.
I think you meant to use a delegating constructor instead. The difference is subtle but important:
Texture2D(const char* imgPath, GLint internalFormat, GLenum format, GLint wrapMode, GLint filterMode)
: Texture2D(imgPath, internalFormat, format, wrapMode, wrapMode, filterMode, filterMode) {}
I am currently experiencing an issue with rendering multiple textures at once with OpenGL 3.3 Core. I load 2 separate images through SOIL ( an image loading library ) but only one of the images appears in the final program. This is my current code:
#include <iostream>
#include <GL\glew.h>
#include <GL\GL.h>
#include <GLFW\glfw3.h>
#include <SOIL.h>
#include "Shader.h"
#include "texture2D.h"
using namespace std;
void processInput(GLFWwindow *window) {
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
glfwSetWindowShouldClose(window, true);
}
}
int main() {
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow *window = glfwCreateWindow(800, 600, "OpenGL", NULL, NULL);
if (window == NULL) {
cout << "GLFW WINDOW CREATION FAILED! " << endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
cout << "Made By Rial Seebran " << endl;
cout << glfwGetVersionString() << endl;
glewInit();
if (glewInit() != GLEW_OK) {
cout << "GLEW INITIALIZATION FAILED! " << endl;
glfwTerminate();
return -1;
}
float positions[] = {
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.0f, 1.0f, 1.0f
};
unsigned int indices[] = {
0, 1, 2,
3, 2, 1
};
unsigned int VAO;
unsigned int VBO;
unsigned int EBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 5, ((GLvoid*)(0)));
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 5, ((GLvoid*)(sizeof(float) * 3)));
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
Shader shader("shader.vs", "shader.fs");
Texture2D texture1;
texture1.LoadTexture("container.jpg");
Texture2D texture2;
texture2.LoadTexture("awesomeface.png");
shader.Use();
while (!glfwWindowShouldClose(window)) {
glClearColor(0.1f, 0.15f, 0.2f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
texture1.BindTexture(0);
texture2.BindTexture(1);
shader.Uniform1I("myTexture1", 0);
shader.Uniform1I("myTexture2", 1);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
processInput(window);
glfwPollEvents();
glfwSwapBuffers(window);
}
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteBuffers(1, &EBO);
glfwTerminate();
return 0;
}
And this is the texture class (all in a .h file):
#ifndef TEXTURE2D
#define TEXTURE2D
#include <GL\glew.h>
#include <GL\GL.h>
#include <SOIL.h>
#include <iostream>
using namespace std;
class Texture2D {
public:
Texture2D();
~Texture2D();
void LoadTexture(const char* texPath);
void BindTexture(unsigned int texUnit);
unsigned int texture_M;
};
Texture2D::Texture2D() {
}
Texture2D::~Texture2D() {
glDeleteTextures(1, &texture_M);
}
void Texture2D::LoadTexture(const char* texPath) {
int width;
int height;
unsigned char *image = SOIL_load_image(texPath, &width, &height, 0, SOIL_LOAD_RGBA);
if (image == NULL) {
cout << "Failed to load Image! " << endl;
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, texture_M);
if (image != NULL) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
glGenerateMipmap(GL_TEXTURE_2D);
}
SOIL_free_image_data(image);
glBindTexture(GL_TEXTURE_2D, 0);
}
void Texture2D::BindTexture(unsigned int texUnit) {
glActiveTexture(GL_TEXTURE0 + texUnit);
glBindTexture(GL_TEXTURE_2D, texture_M);
}
#endif
In the fragment shader, I use the mix() function which linearly interpolates the 2 textures, yet the "awesomeface.png" image is the only texture which shows up in the final program. What should be fixed, for the program to display both textures?
You have to add the following line at the beggining of Texture::LoadTexture() to generate the texture ID:
glGenTextures(1, &texture_M);
This will reserve a valid ID used to identify the texture object (that will later have to be initialized by a call to glBindTexture()). It can be used to reference the texture in subsequent OpenGL calls (including deleting the texture using glDeleteTextures()).
When a unused name is bound to a texture target by glBindTexture, then a texture object is generated.
But a new unused texture name has to be reserved by glGenTextures.
The texture parameters which set by glTexParameteri are set to the texture object which is bound to the specified target.
Reserve the unused texture name, then create the texture object. After that you can set the parameters and specify the two-dimensional texture image.
// 1. reserve texture name
glGenTextures(1, &texture_M);
// 2. generate texture object
glBindTexture(GL_TEXTURE_2D, texture_M);
// set parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// generate texture image
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
glGenerateMipmap(GL_TEXTURE_2D);
I did not call glGenTextures() in the texture2D class. Thanks to stackOverflow user #Rabbid76 for pointing that out
I'm having a problem rendering my sprite even though I have initialized glew.
Here's my code:
#include <glew.h>
#include <wglew.h>
#include <stdio.h>
#include <iostream>
#include <gl\GL.h>
#include <SDL.h>
#include "SDL_image.h"
GLuint _texturebufferID;
GLuint _vertexBufferID;
GLuint texturebufferID;
int SCREEN_WIDTH = 740;
int SCREEN_HEIGHT = 520;
int mode;
bool processing = true;
SDL_Surface* image;
SDL_Window* window;
SDL_Renderer* renderer;
SDL_GLContext context;
SDL_Surface* surface;
SDL_Event window_key;
typedef struct {
GLfloat positionCoordinates[3];
GLfloat textureCoordinates[2];
} Texture;
Texture vertices[] =
{
// | Pixels |--|coords|
{{1.0f, 0.0f, 0.0f}, {0.0f, 0.0f}},
{{0.0f, 43.0f, 0.0f}, {0.0f, 1.0f}},
{{168.0f, 43.0f, 0.0f}, {1.0f, 1.0f}},
{{168.0f, 0.0f, 0.0f}, {1.0f, 0.0f}}
};
GLuint loadandbuffersprite(const char *filename)
{
image = IMG_Load(filename);
if (image->format->BytesPerPixel == 3)
{
mode = GL_RGB;
}
else if (image->format->BytesPerPixel == 4)
{
mode = GL_RGBA;
}
else
{
SDL_FreeSurface(image);
return 0;
}
glGenTextures(1, &texturebufferID);
glBindTexture(GL_TEXTURE_2D, texturebufferID);
glTexImage2D(GL_TEXTURE_2D, 0, mode, image->w, image->h,
0, mode, GL_UNSIGNED_BYTE, image->pixels);
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_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
SDL_FreeSurface( image );
return texturebufferID;
}
void render()
{
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glMatrixMode(GL_PROJECTION);
glMatrixMode(GL_MODELVIEW);
glGenBuffers(1, &_vertexBufferID);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferID);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices,
GL_STATIC_DRAW);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(Texture), (GLvoid *)
offsetof(Texture, positionCoordinates));
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(Texture), (GLvoid *)
offsetof(Texture, textureCoordinates));
glLoadIdentity();
_texturebufferID = loadandbuffersprite("hane_stand.png");
}
// |----------------------------------------|
// | Main function |
// |----------------------------------------|
int main(int argc, char *argv[])
{
SDL_Init(SDL_INIT_EVERYTHING);
// Intialize everything.
window = SDL_CreateWindow
(
"render example",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
SCREEN_WIDTH,
SCREEN_HEIGHT,
SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE
);
// Create window for rendering.
glewInit();
renderer = SDL_CreateRenderer(window, -1, 0);
context = SDL_GL_CreateContext(window);
SDL_GL_MakeCurrent(window, context);
SDL_GL_LoadLibrary( NULL );
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
// Clearing color
glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
// Set viewport
// |----------------------------------------|
// | Game loop |
// |----------------------------------------|
while (processing)
{
glClear(GL_COLOR_BUFFER_BIT);
render();
glDrawArrays(GL_QUADS, 0, 4);
SDL_RenderPresent(renderer);
SDL_GL_SwapWindow(window);
}
glDeleteTextures( 1, &texturebufferID);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
It's just this problem that's been hammering my coding progression for months and really need help. Anyone have any ideas on how I could fix this?
As for my computer information I use a Toshiba satellite with an AMD C-50 Processor and 2.0 GB of RAM.
I've written a program for testing rendering a texture with the framebuffer. In the function render_texture() I want to render a triangle on to a texture, but when I display the rendered texture in the display function, I get just a simple yellow square.
#include "GL/glew.h"
#include "GL/glext.h"
#include "GL/glu.h"
#include "GL/freeglut.h"
#include <cstdio>
uint16_t tex_width = 75;
uint16_t tex_height = 24;
GLuint texture;
int w1;
int h1;
void orthogonalStart (int w, int h) {
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0, w, 0, h);
glScalef(1, -1, 1);
glTranslatef(0, -h1, 0);
glMatrixMode(GL_MODELVIEW);
}
void orthogonalEnd (void) {
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
}
void display (void) {
glClearColor (0.0,0.0,0.0,1.0);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
orthogonalStart(w1, h1);
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex2f(125, 125);
glTexCoord2f(0, 1); glVertex2f(125, 125+tex_height);
glTexCoord2f(1, 1); glVertex2f(125+tex_width, 125+tex_height);
glTexCoord2f(1, 0); glVertex2f(125+tex_width, 125);
glEnd();
orthogonalEnd();
glutSwapBuffers();
}
void reshape (int w, int h) {
glViewport (0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective (60, (GLfloat)w / (GLfloat)h, 0.1, 1000.0);
w1 = w;
h1 = h;
glMatrixMode (GL_MODELVIEW);
}
void render_texture()
{
GLuint framebuffer = 0;
glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_width, tex_height, 0, GL_RGBA,
GL_UNSIGNED_BYTE, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
GLenum draw_buffers[1] = {GL_COLOR_ATTACHMENT0};
glDrawBuffers(1, draw_buffers);
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
fprintf(stderr, "[render_texture] Fehler im Framebuffer\n");
exit(1);
}
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glViewport(0, 0, tex_width, tex_height);
glClearColor (0.0,0.0,0.0,1.0);
orthogonalStart(tex_width, tex_height);
glColor4f(1, 1, 0, 0);
glBegin(GL_TRIANGLES);
glVertex2f(0.f,0.f);
glVertex2f(tex_width, 0.0f);
glVertex2f(tex_width, (GLfloat)tex_height/2.f);
//glVertex2f(tex_width-(GLfloat)tex_height/2.f, tex_height);
//glVertex2f(0, tex_height);
glEnd();
orthogonalEnd();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
int main (int argc, char **argv) {
glutInit (&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGBA);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow ("");
glutDisplayFunc (display);
glutIdleFunc (display);
glutReshapeFunc (reshape);
glewExperimental=true;
GLenum err=glewInit();
if(err!=GLEW_OK)
{
//Problem: glewInit failed, something is seriously wrong.
fprintf(stderr, "glewInit failed, aborting.\n");
}
render_texture();
glutMainLoop ();
return 0;
}
Edit 1: I've updated the code, now I have just a blank black screen
#include "GL/glew.h"
#include "GL/glext.h"
#include "GL/glu.h"
#include "GL/freeglut.h"
#include <cstdio>
uint16_t tex_width = 75;
uint16_t tex_height = 24;
GLuint texture;
void orthogonalStart (int w, int h) {
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0, w, 0, h);
glScalef(1, -1, 1);
glTranslatef(0, -glutGet(GLUT_WINDOW_HEIGHT), 0);
glMatrixMode(GL_MODELVIEW);
}
void orthogonalEnd (void) {
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
}
void display (void) {
glClearColor (0.0,0.0,0.0,1.0);
glClear (GL_COLOR_BUFFER_BIT);
glLoadIdentity();
orthogonalStart(glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT));
glColor3f(1,1,1);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex2f(125, 125);
glTexCoord2f(0, 1); glVertex2f(125, 125+tex_height);
glTexCoord2f(1, 1); glVertex2f(125+tex_width, 125+tex_height);
glTexCoord2f(1, 0); glVertex2f(125+tex_width, 125);
glEnd();
glDisable(GL_TEXTURE_2D);
orthogonalEnd();
glutSwapBuffers();
}
void reshape (int w, int h) {
glViewport (0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective (60, (GLfloat)w / (GLfloat)h, 0.1, 1000.0);
glMatrixMode (GL_MODELVIEW);
}
void render_texture()
{
GLuint framebuffer = 0;
glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_width, tex_height, 0, GL_RGBA,
GL_UNSIGNED_BYTE, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
GLenum draw_buffers[1] = {GL_COLOR_ATTACHMENT0};
glDrawBuffers(1, draw_buffers);
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
fprintf(stderr, "[render_texture] Fehler im Framebuffer\n");
exit(1);
}
glViewport(0, 0, tex_width, tex_height);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
orthogonalStart(tex_width, tex_height);
glColor4f(1, 1, 0, 0);
glBegin(GL_TRIANGLES);
glVertex2f(0.f,0.f);
glVertex2f(tex_width, 0.0f);
glVertex2f(tex_width, (GLfloat)tex_height/2.f);
//glVertex2f(tex_width-(GLfloat)tex_height/2.f, tex_height);
//glVertex2f(0, tex_height);
glEnd();
orthogonalEnd();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
int main (int argc, char **argv) {
glutInit (&argc, argv);
glutInitContextVersion(3, 1);
glutInitContextProfile(GLUT_CORE_PROFILE);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowSize (500, 500);
glutCreateWindow ("");
glutDisplayFunc (display);
glutIdleFunc (display);
glutReshapeFunc (reshape);
glewExperimental=true;
GLenum err=glewInit();
if(err!=GLEW_OK)
{
//Problem: glewInit failed, something is seriously wrong.
fprintf(stderr, "glewInit failed, aborting.\n");
}
//glEnable(GL_TEXTURE_2D);
render_texture();
glutMainLoop ();
return 0;
}
You are clearly doing something wrong in the setup of your projection matrix.
I'm not sure why you are calling glScalef() and glTranslatef(), if you comment out these lines in your orthogonalStart() function, you'll have your triangle.
void orthogonalStart (int w, int h) {
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0, w, 0, h);
//glScalef(1, -1, 1);
//glTranslatef(0, -glutGet(GLUT_WINDOW_HEIGHT), 0);
glMatrixMode(GL_MODELVIEW);
}
On a sidenote, there is no need to call glBindFramebuffer(GL_FRAMEBUFFER, framebuffer) a 2nd time in your render_texture() function call.
Also, I would recommend you to start learning about vertex buffers to draw your objects, which is more elaborated here.