Related
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 creating a custom framebuffer of size 1920 X 1080 and then mapping the texture of this frame buffer to a full screen rectangle in default frame buffer of size 800 X 600.
I had drawn a rectangle in the center of the screen in the custom frame buffer and after mapping the texture i was expecting the rectangle to appear in the center.
But the rectangle appeared in the lower left corner.
when i draw a full screen rectangle in the custom buffer and map it to the full screen rectangle in the default frame buffer of size 800 X 600 instead of appearing fullscreen it covers the entire lower left corner.
SCR_WIDTH = 800;
SCR_HEIGHT = 600;
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
cont.SetName("RootItem");
TreeModel* model = new TreeModel("RootElement", &cont);
WavefrontRenderer w(model);
w.show();
glfwInit();
int return_code;
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "Renderer", nullptr, nullptr); // Create the render window
glfwSetWindowPos(window, 1120, 480);
glfwFocusWindow(window);
glfwMakeContextCurrent(window);
GLenum GlewInitResult;
glewExperimental = GL_TRUE;
GlewInitResult = glewInit();
glEnable(GL_MULTISAMPLE);
glEnable(GL_DEPTH_TEST);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
ResourceManager::LoadShader("C:\\Shaders\\Test\\Vert.txt", "C:\\Shaders\\Test\\Frag.txt", nullptr, "ScreenShader");
//create a texture object
glGenTextures(1, &textureId);
glBindTexture(GL_TEXTURE_2D, textureId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1920, 1080, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glBindTexture(GL_TEXTURE_2D, 0);
// create a renderbuffer object for depthbuffer
glGenRenderbuffers(1, &rboDepthId);
glBindRenderbuffer(GL_RENDERBUFFER, rboDepthId);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, 1920, 1080);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
// create a framebuffer
glGenFramebuffers(1, &fboMsaaId);
glBindFramebuffer(GL_FRAMEBUFFER, fboMsaaId);
// attach colorbuffer image to FBO
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId , 0);
// attach depthbuffer image to FBO
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboDepthId);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
while (!glfwWindowShouldClose(window))
{
glBindFramebuffer(GL_FRAMEBUFFER, fboMsaaId);
glClearColor(1.0, 0.0, 0.0, 1.0);
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
w.render(); // Do rendering here
ResourceManager::GetShader("ScreenShader").Use();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDisable(GL_DEPTH_TEST);
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
ResourceManager::GetShader("ScreenShader").Use();
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textureId);
renderQuad();
glfwPollEvents();
glfwSwapBuffers(window);
}
glfwTerminate();
return a.exec();
}
/////////////////////////////////////////////////////////////////////////////////////////////////// Defination for Render Quad function
unsigned int quadVAO = 0;
unsigned int quadVBO;
void renderQuad()
{
if (quadVAO == 0)
{
float quadVertices[] = { // vertex attributes for a quad that fills the entire screen in Normalized Device Coordinates.
// positions // texCoords
-1.0f, 1.0f, 0.0f, 1.0f,
-1.0f, -1.0f, 0.0f, 0.0f,
1.0f, -1.0f, 1.0f, 0.0f,
-1.0f, 1.0f, 0.0f, 1.0f,
1.0f, -1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 1.0f, 1.0f
};
// VAO
glGenVertexArrays(1, &quadVAO);
glGenBuffers(1, &quadVBO);
glBindVertexArray(quadVAO);
glBindBuffer(GL_ARRAY_BUFFER, quadVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float)));
}
glBindVertexArray(quadVAO);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 6);
glBindVertexArray(0);
}
You have to adjust the viewport to the new size, when you switch between framebuffers with different sizes. Use glViewport to set the viewport. The size of the default framebuffer can be get by glfwGetFramebufferSize (the size of the window framebuffer changes when the size of the window is changed).
Furthermore OpenGL is a state engine. States are persistent until they are changed again, even beyond frames. If the first pass uses the Depth Test, but the 2nd pass does not, then the depth test has to be switched on and off in the loop:
int main(int argc, char *argv[])
{
// [...]
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1920, 1080, ....);
// [...]
while (!glfwWindowShouldClose(window))
{
int sizex, sizey;
glfwGetFramebufferSize(window, &sizex, &sizey);
glBindFramebuffer(GL_FRAMEBUFFER, fboMsaaId);
glViewport(0, 0, 1920, 1080);
glClearColor(1.0, 0.0, 0.0, 1.0);
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glEnable(GL_DEPTH_TEST);
// [...]
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, sizex, sizey);
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
// [...]
}
}
I keep having issues with glTexImage2D and it is stopping me from rendering to the screen.
Here is 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);
glGenTextures(1, &texturebufferID);
glBindTexture(GL_TEXTURE_2D, texturebufferID);
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);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image->w, image->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, image->pixels); //Access Violation
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();
loadandbuffersprite("hane_stand.png");
}
I've just got the error recently but I don't understand what the problem could be. Could any point me in the right direction?
The only real problem is that you never Enabled GL_TEXTURE_2D for 2D rendering.
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.
I need to be able to stretch the image texture i'm importing over the entire 2d or 3d (face) shape. It will only render in the top right of the shape, and either repeat - if I enable GL_REPEAT, or the image will stretch from the sides projecting to the edge horribly if i enable GL_CLAMP.
Here's my code:
#include "stdafx.h"
#include "glut.h"
#include <stdio.h>
#include <windows.h>
#include <stdlib.h>
GLuint texture;
float xRotation = 0.0f;
void drawScene1 (void) {
//glRotatef(xRotation,0.0f,1.0f,0.0f);
glBindTexture(GL_TEXTURE_2D, texture);
//glutSolidCube(1.0f);
glBegin(GL_POLYGON);
glTexCoord2d(0,1);
glVertex2d(-1.5,-1.5);
glTexCoord2d(1,1);
glVertex2d(1.0,-2.0);
glTexCoord2d(1,0);
glVertex2d(+1.5,+1.5);
glTexCoord2d(0,0);
glVertex2d(-1.5,+1.5);
glEnd();
}
void FreeTexture(GLuint texture) {
glDeleteTextures(1, &texture);
}
GLuint LoadTexture(const char * filename, int width, int height) {
GLuint texture;
unsigned char * data;
FILE * file;
file = fopen(filename, "rb");
if ( file == NULL ) return 0;
data = (unsigned char *)malloc(width * height * 3);
fread(data, width * height * 3, 1, file);
fclose(file);
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
//glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, width, height, GL_RGB, GL_UNSIGNED_BYTE, data);
free(data);
return texture;
}
void init (void) {
glShadeModel(GL_SMOOTH);
glMatrixMode(GL_PROJECTION);
//glLoadIdentity();
//gluOrtho2D(0,500,0,500);
//glClearDepth(1);
//glEnable (GL_DEPTH_TEST);
//glEnable (GL_LIGHTING);
//glEnable (GL_LIGHT0);
//glEnable(GL_COLOR_MATERIAL);
glEnable(GL_NORMALIZE);
glEnable(GL_TEXTURE_2D);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
}
void display (void) {
glClearColor(0.05,0.05,0.1,1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
texture = LoadTexture("img.raw", 256, 256);
drawScene1();
FreeTexture(texture);
glutSwapBuffers();
xRotation++;
}
int main (int argc, char **argv) {
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(500,500);
glutInitWindowPosition(100,100);
glutCreateWindow("Virgin");
init();
glutDisplayFunc(display);
glutIdleFunc(display);
glutMainLoop();
return 0;
}
Please decide: Implicit texture coordinate generation:
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
or explicit texture coordinate supplications:
glTexCoord(...)
Implicit will override explicit.
void display (void) {
/*... */
texture = LoadTexture("img.raw", 256, 256);
drawScene1();
FreeTexture(texture);
/* ... */
}
Don't load and delete the texture for each rendered frame. Load the textures at startup and only bind them when rendering.
Remove the following lines:
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
You already have texture coordinates entered via glTexCoord2f(), no need to generate them.