Here is the diver code:
camera.projection = CGL_mat4_perspective(((float)rx / ry), camera.fov, 0.01f, 100.0f);
camera.view = CGL_mat4_look_at(camera.pos, CGL_vec3_init(camera.pos.x, camera.pos.y,
camera.pos.z + 1.0f), CGL_vec3_init(0.0f, 1.0f, 0.0f));
CGL_shader_set_uniform_mat4(main_shader.shader, main_shader.u_projection, &camera.projection);
CGL_shader_set_uniform_mat4(main_shader.shader, main_shader.u_view, &camera.view);
The functions:
#define CGL_mat4_perspective(aspect, fov, znear, zfar) (CGL_mat4){1.0f / (aspect * tanf(fov / 2.0f)), 0.0f, 0.0f, 0.0f, 0.0f, 1.0f / tanf(fov / 2.0f), 0.0f, 0.0f, 0.0f, 0.0f, -1.0f * ( (zfar + znear) / (zfar - znear) ), -1.0f, 0.0f, 0.0f, -2.0f * znear * zfar / (zfar - znear), 1.0f}
CGL_mat4 CGL_mat4_look_at(CGL_vec3 eye, CGL_vec3 target, CGL_vec3 up)
{
CGL_vec3 z_axis = CGL_vec3_sub(target, eye);
CGL_vec3_normalize(z_axis);
CGL_vec3 x_axis = CGL_vec3_cross(up, z_axis);
CGL_vec3_normalize(x_axis);
CGL_vec3 y_axis = CGL_vec3_cross(z_axis, x_axis);
CGL_mat4 mat;
mat.m[0] = x_axis.x;
mat.m[1] = x_axis.y;
mat.m[2] = x_axis.z;
mat.m[3] = -1.0f * CGL_vec3_dot(x_axis, eye);
mat.m[4] = y_axis.x;
mat.m[5] = y_axis.y;
mat.m[6] = y_axis.z;
mat.m[7] = -1.0f * CGL_vec3_dot(y_axis, eye);
mat.m[8] = z_axis.x;
mat.m[9] = z_axis.y;
mat.m[10] = z_axis.z;
mat.m[11] = -1.0f * CGL_vec3_dot(z_axis, eye);
mat.m[12] = 0.0f;
mat.m[13] = 0.0f;
mat.m[14] = 0.0f;
mat.m[15] = 1.0f;
return mat;
}
The shader:
gl_Position = u_projection * u_view * vec4(position.xyz, 1.0f);
However when the camera.pos is changed the plane that is being rendered is being rotated rather than being translated.
Related
arrayOfPaint[i] = new GradientPaint(0.0F, 0.0F, Color.green, 0.0F, 0.0F, Color.green);
// arrayOfPaint[i] = new GradientPaint(0.0F, 0.0F, Color.red, 0.0F, 0.0F, Color.red);
}
}
}
/* arrayOfPaint[0] = new GradientPaint(0.0F, 0.0F, Color.red, 0.0F, 0.0F, Color.red);
arrayOfPaint[1] = new GradientPaint(0.0F, 0.0F, Color.green, 0.0F, 0.0F, Color.green);
arrayOfPaint[2] = new GradientPaint(0.0F, 0.0F, Color.blue, 0.0F, 0.0F, Color.blue); */
CategoryDataset paramCategoryDatasetCylinder = localDefaultCategoryDatasetCylinder;
JFreeChart localJFreeChartCylinder = ChartFactory.createBarChart3D("", "Section", "Percentage", paramCategoryDatasetCylinder ,PlotOrientation.HORIZONTAL, true, true, false);
CategoryPlot localCategoryPlotCylinder = (CategoryPlot)localJFreeChartCylinder.getPlot();
/* if(compCode.equalsIgnoreCase("0094000") && domainName.equalsIgnoreCase("L and T")){
CategoryAxis yAxis = (CategoryAxis)localCategoryPlotCylinder.getDomainAxis();
yAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_45);
} */
localCategoryPlotCylinder.setBackgroundPaint(Color.white);
localCategoryPlotCylinder.setRangeGridlinesVisible(true);
localCategoryPlotCylinder.setRangeGridlinePaint(Color.BLACK);
localJFreeChartCylinder.setBackgroundPaint(new GradientPaint(0.0F, 0.0F, Color.white, 350.0F, 0.0F, Color.white, true));
I have set GREEN color for both of the bars but I am getting difference in color. I am unable to figure out why it is happpening. Please help in this regard
The problem I'm having is that I'm exporting a scene from Blender and my scene is rotated 90 about the Y axis. It's clearly a matrix issue and I'm having problems visualizing the solution. Blender is configured to export with 'up' = (0, 1, 0) and 'forward' = (0, 0, 1).
I'm using row major matrices as indicated by the following.
mat4x4 cons_mat4x4_perspective(float fovy, float aspect_ratio, float near, float far)
{
mat4x4 result = cons_mat4x4_zero();
float half_tan_fovy = tan(fovy / 2.0f); /* in radians */
result.as_rows[0] = cons_vec4(1.0f / (aspect_ratio * half_tan_fovy), 0.0f, 0.0f, 0.0f);
result.as_rows[1] = cons_vec4(0.0f, 1.0f / half_tan_fovy, 0.0f, 0.0f);
result.as_rows[2] = cons_vec4(0.0f, 0.0f, -(far + near) / (far - near), -1.0f);
result.as_rows[3] = cons_vec4(0.0f, 0.0f, -(2.0f * far * near) / (far - near), 0.0f);
return result;
}
// Vulkan clip matrix
clip = cons_mat4x4_floats(1.0f, 0.0f, 0.0f, 0.0f,
0.0f,-1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.5f, 0.0f,
0.0f, 0.0f, 0.5f, 1.0f);
mat4x4 cons_mat4x4_lookat(vec3 eye, vec3 center, vec3 up)
{
mat4x4 result = cons_mat4x4_identity();
vec3 f = normalize(vec3_sub(center, eye));
vec3 s = normalize(cross(f, up));
vec3 u = cross(s, f);
result.as_rows[0] = cons_vec4(s.x, u.x, -f.x, 0.0f);
result.as_rows[1] = cons_vec4(s.y, u.y, -f.y, 0.0f);
result.as_rows[2] = cons_vec4(s.z, u.z, -f.z, 0.0f);
result.as_rows[3] = cons_vec4(-vec3_dot(s, eye),
vec3_dot(u, eye),
vec3_dot(f, eye),
1.0f);
return result;
}
My model matrix is the identity matrix and I'm creating a lookat matrix with the following parameters:
vec3 _camera = cons_vec3(0.0f, 5.0f, 0.0f);
vec3 _at = cons_vec3(0.0f, 0.0f, 0.0f);
cons_mat4x4_lookat(_camera, _at, cons_vec3(0.0f, 1.0f, 0.0f));
I tried to convert the code of the question I asked over here.
But when I try to run it, I run into an exception and it points to the mat4(which is an 2-d array of 4x4 floats) header of this(CGLM, which is use for OpenGL math in C as GLM is C++ only library) library.
The C++ code works fine and runs perfectly but why does it crash in C.
Here is the C snippet of the code where 'CGLM' is used(this is the code that crashes):-
glUseProgram(shaderProgram);
mat4 model =
{
{ 1.0f, 0.0f, 0.0f, 0.0f },
{ 0.0f, 1.0f, 0.0f, 0.0f },
{ 0.0f, 0.0f, 1.0f, 0.0f },
{ 0.0f, 0.0f, 0.0f, 1.0f },
};
mat4 projection;
glm_ortho(0.0f, (GLfloat)(WIDTH), (GLfloat)(HEIGHT), 0.0f, -1.0f, 1.0f, projection);
vect2 scale = { 2.0f, 2.0f };
vect2 position = { 50.0f, 0.0f };
vec4 color = { 1.0f, 1.0f, 1.0f, 0.5f };
GLfloat rotation = 0.0f;
glm_translate(model, (vec3){ position[0], position[1], 0.0f });
glm_translate(model, (vec3){ 0.5f * scale[0], 0.5f * scale[1], 0.0f });
glm_rotate(model, rotation, (vec3){ 0.0f, 0.0f, 1.0f }); // Why is this function crashing?
glm_translate(model, (vec3){ -0.5f * scale[0], -0.5f * scale[1], 0.0f });
glm_scale(model, (vec3){ scale[0] * width, scale[1] * height, 1.0f });
glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "projection"), 1, GL_FALSE, (GLfloat *)projection);
glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "model"), 1, GL_FALSE, (GLfloat *)model);
glUniform4f(glGetUniformLocation(shaderProgram, "spriteColor"), color[0], color[1], color[2], color[3]);
Here is the C++ snippet of the code where GLM is used:-
glUseProgram(shaderProgram);
glm::mat4 model(1.0f);
glm::mat4 projection = glm::ortho(0.0f, static_cast<GLfloat>(WIDTH), static_cast<GLfloat>(HEIGHT), 0.0f, -1.0f, 1.0f);
glm::vec2 scale = glm::vec2(2.0f, 2.0f);
glm::vec2 position = glm::vec2(50.0f, 0.0f);
glm::vec4 color = glm::vec4(1.0f, 1.0f, 1.0f, 0.5f);
GLfloat rotation = 0.0f;
model = glm::translate(model, glm::vec3(position, 0.0f));
model = glm::translate(model, glm::vec3(0.5f * scale.x, 0.5f * scale.y, 0.0f));
model = glm::rotate(model, rotation, glm::vec3(0.0f, 0.0f, 1.0f));
model = glm::translate(model, glm::vec3(-0.5f * scale.x, -0.5f * scale.y, 0.0f));
model = glm::scale(model, glm::vec3(scale * glm::vec2(width, height), 1.0f));
glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "projection"), 1, GL_FALSE, glm::value_ptr(projection));
glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "model"), 1, GL_FALSE, glm::value_ptr(model));
glUniform4f(glGetUniformLocation(shaderProgram, "spriteColor"), color.x, color.y, color.z, color.w);
See CGLM documentation
According to the getting started
Aligment is Required: vec4 and mat4 requires 16 byte aligment because
vec4 and mat4 operations are vectorized by SIMD instructions
(SSE/AVX).
So you need to initialize identity matrix like:
mat4 model;
glm_mat4_identity(model);
....
mat4 projection;
glm_mat4_identity(projection);
glm_ortho(0.0f, (GLfloat)(WIDTH), (GLfloat)(HEIGHT), 0.0f, -1.0f, 1.0f, projection);
I've been working on the transformations tutorial from open.gl and am having trouble making my perspective projection matrix work. The tutorial uses GLM, but I chose to roll my own matrix math functions to try and learn the math a little better. Everything compiles fine (gcc -Wall), and my rotation and lookat matrix functions are working perfectly, but my perspective projection matrix causes a black screen with no OpenGL errors.
The projection matrix is (I think) supposed to be
/ cot(fovy/2)/aspect 0.0 0.0 0.0 \
| 0.0 cot(fovy/2) 0.0 0.0 |
| 0.0 0.0 (zfar + znear)/(znear - zfar) -1.0 |
\ 0.0 0.0 (2 * zfar * znear)/(znear - zfar) 0.0 /
Interestingly, I can provide the intended effect with the matrix
/ cot(fovy/2)/aspect 0.0 0.0 0.0 \
| 0.0 cot(fovy/2) 0.0 0.0 |
| 0.0 0.0 (zfar + znear)/(znear - zfar) -1.0 |
\ 0.0 0.0 0.4 1.0 /
Here are the necessary source files. You'll need GLFW3 and SOIL to compile the code -- I've been using gcc -Wall -Werror -std=c99 -lGL -lGLEW -lglfw -lm -lSOIL transform.c -o transform. I've tried to provide shorter (non-compiling) versions of the source below in case there are any glaring errors.
transform.c:
#include <math.h>
#define M_PI (3.14159265358979323846)
#include <stdio.h>
#include <stdlib.h>
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <SOIL/SOIL.h>
typedef struct mat4_t {
float arr[16];
} mat4_t;
typedef struct vec3_t {
float arr[3];
} vec3_t;
/* forward declarations... */
/* return a 4x4 'lookat' matrix to be multiplied by model space coords */
mat4_t mat4mklook(const vec3_t eye, const vec3_t center, const vec3_t up) {
/* check out the OpenGL gluLookAt documentation for an explanation */
vec3_t f = vec3norm(vec3sub(center, eye));
vec3_t up_ = vec3norm(up);
vec3_t s = vec3cross(f, up_);
vec3_t u = vec3cross(s, f);
return (mat4_t) { {
s.arr[0], s.arr[1], s.arr[2], 0.0f,
u.arr[0], u.arr[1], u.arr[2], 0.0f,
-f.arr[0], -f.arr[1], -f.arr[2], 0.0f,
0.0f, 0.0f, 0.0f, 1.0f
} };
}
/* return a 4x4 persp. projection matrix to be multiplied by camera coords */
mat4_t mat4mkproj(const float fovy, const float aspect, const float znear, const float zfar) {
float f = 1 / tan(fovy / 2.0f);
return (mat4_t){ {
f/aspect, 0.0f, 0.0f, 0.0f,
0.0f, f, 0.0f, 0.0f,
0.0f, 0.0f, (zfar+znear)/(znear-zfar), (2*zfar*znear)/(znear-zfar),
0.0f, 0.0f, -1.0f, 0.0f
} };
}
/* returns a 4x4 rotation matrix of magnitude 'th' about unit vector 'axis' */
mat4_t mat4mkrot(const vec3_t axis, const float th) {
const float uX = axis.arr[0];
const float uY = axis.arr[1];
const float uZ = axis.arr[2];
const float sinth = sin(th);
const float costh = cos(th);
return (mat4_t) { {
costh+pow(uX,2)*(1-costh), uX*uY*(1-costh)-uZ*sinth, uX*uZ*(1-costh)+uY*sinth, 0.0,
uY*uX*(1-costh)+uZ*sinth, costh+pow(uY,2)*(1-costh), uY*uZ*(1-costh)-uX*sinth, 0.0,
uZ*uX*(1-costh)-uY*sinth, uZ*uY*(1-costh)+uX*sinth, costh+pow(uZ,2)*(1-costh), 0.0,
0.0, 0.0, 0.0, 1.0
} };
}
/* returns the product of matrices 'a' and 'b' */
mat4_t mat4mult(const mat4_t a, const mat4_t b) {
mat4_t result;
for(int i = 0; i < 16; ++i) {
result.arr[i] = 0.0f;
for(int j = 0; j < 4; ++j) {
result.arr[i] += a.arr[i / 4 + j] * b.arr[i % 4 + j * 4];
}
}
return result;
}
/* returns the cross product of vectors 'a' and 'b' */
vec3_t vec3cross(const vec3_t a, const vec3_t b) {
return (vec3_t){ {
a.arr[1] * b.arr[2] - a.arr[2] * b.arr[1],
a.arr[2] * b.arr[0] - a.arr[0] * b.arr[2],
a.arr[0] * b.arr[1] - a.arr[1] * b.arr[0]
} };
}
/* returns a unit vector derived from vector 'v' */
vec3_t vec3norm(const vec3_t a) {
vec3_t result;
float mag;
if((mag = sqrt(pow(a.arr[0], 2) + pow(a.arr[1], 2) + pow(a.arr[2], 2))) == 0.0f) {
result = (vec3_t) {{0}};
} else {
for(int i = 0; i < 3; ++i) {
result.arr[i] = a.arr[i] / mag;
}
}
return result;
}
/* return the vector difference 'a' - 'b' */
vec3_t vec3sub(const vec3_t a, const vec3_t b) {
vec3_t result;
for(int i = 0; i < 3; ++i) {
result.arr[i] = a.arr[i] - b.arr[i];
}
return result;
}
/* returns the dot product of vectors 'a' and 'b' */
float vec3dot(const vec3_t a, const vec3_t b) {
return a.arr[0] * b.arr[0] +
a.arr[1] * b.arr[1] +
a.arr[2] * b.arr[2];
}
GLfloat vertices[] = {
/* position texture */
-0.5f, 0.5f, 0.0f, 0.0f,
0.5f, 0.5f, 1.0f, 0.0f,
0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, -0.5f, 0.0f, 1.0f
};
GLuint elements[] = {
0, 1, 2,
2, 3, 0
};
int main() {
glfwInit();
/* context settings */
/* window & context creation */
GLFWwindow * const window = glfwCreateWindow(800, 600, "OpenGL", NULL, NULL);
glfwMakeContextCurrent(window);
/* glew initialization -- generates harmless error */
glewExperimental = GL_TRUE;
glewInit();
glGetError();
/* vertex setup */
/* shader setup */
/* vertex attribute setup */
/* texture setup */
GLint modeluni;
{ /* matrix uniform setup */
modeluni = glGetUniformLocation(shaderProgram, "model");
mat4_t viewmat = mat4mklook((vec3_t){{1.2f, 1.2f, 1.2f}}, (vec3_t){{0.0f, 0.0f, 0.0f}}, (vec3_t){{0.0f, 0.0f, 1.0f}});
GLint viewuni = glGetUniformLocation(shaderProgram, "view");
glUniformMatrix4fv(viewuni, 1, GL_TRUE, viewmat.arr);
mat4_t projmat = mat4mkproj(M_PI / 4.0f, 800.0f / 600.0f, 1.0f, 10.0f);
GLint projuni = glGetUniformLocation(shaderProgram, "proj");
glUniformMatrix4fv(projuni, 1, GL_TRUE, projmat.arr);
}
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
while(!glfwWindowShouldClose(window)) {
const GLuint error = glGetError();
if(error) {
fprintf(stderr, "%d\n", error);
}
glClear(GL_COLOR_BUFFER_BIT);
mat4_t modmat = mat4mkrot((vec3_t){{0.0f, 0.0f, 1.0f}}, (glfwGetTime() / 2.0) * M_PI);
glUniformMatrix4fv(modeluni, 1, GL_TRUE, modmat.arr);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glfwSwapBuffers(window);
glfwPollEvents();
}
/* delete opengl ids */
glfwTerminate();
return 0;
}
vert.glsl:
#version 330
in vec2 position;
in vec3 color;
in vec2 texcoord;
out vec3 Color;
out vec2 Texcoord;
uniform mat4 model;
uniform mat4 view;
uniform mat4 proj;
void main() {
Color = color;
Texcoord = texcoord;
gl_Position = proj * view * model * vec4(position.x, position.y, 0.0, 1.0);
}
frag.glsl:
#version 330
in vec3 Color;
in vec2 Texcoord;
out vec4 outColor;
uniform sampler2D texKitten;
uniform sampler2D texPuppy;
void main() {
vec4 colKitten = texture(texKitten, Texcoord);
vec4 colPuppy = texture(texPuppy, Texcoord);
outColor = mix(colKitten, colPuppy, 0.5);
}
I have the following matrix;
Vertex axisVertices[] =
{
{ { x_0, y_0, 0.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } }, // origin
{ { x_Max, y_0, 0.0f, 1.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } }, // eixo y
{ { x_0, y_Max, 0.0f, 1.0f }, { 0.0f, 0.0f, 1.0f, 1.0f } } // eixo x
};
#define x_0 0.0f
#define y_0 0.0f
#define x_Max 1.5f
#define y_Max 1.7f
I need to be able to initialize the matrix like this. The only possible way of doing this in C is by defining either an enum, or using #define because initializing like this can't be used with a constant.
The problem is, I need to be able to change the values x_Max and y_Max throughout the code, so #define wont work in this case. How can I accomplish this?
You can pass parameters to #defines to create macros
For example you can do
#define INIT(x_0, y_0, x_Max, y_Max) \
{ { { x_0, y_0, 0.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } }, \
{ { x_Max, y_0, 0.0f, 1.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } }, \
{ { x_0, y_Max, 0.0f, 1.0f }, { 0.0f, 0.0f, 1.0f, 1.0f } } }
Which you can use like this
Vertex axisVertices[] = INIT(0.0f, 0.0f, 1.5f, 1.7f);
Then all occurrences of x_0 will be replaces by 0.0f. Just like passing parameters to functions.